FancySafeBot 0.0.1
A safe robotics library
Loading...
Searching...
No Matches
fsb_work.h
1
2#ifndef FSB_WORK_H
3#define FSB_WORK_H
4
5#include <array>
6#include <cstddef>
7#include <cstdint>
8
9namespace fsb
10{
11
27enum class WorkArrayStatus : uint8_t
28{
30 SUCCESS = 0,
32 FULL,
37};
38
42template <typename T> struct WorkBlock
43{
44 T* data = nullptr;
45 size_t size = 0;
46 size_t offset = 0;
47
48 [[nodiscard]] explicit operator bool() const noexcept
49 {
50 return (data != nullptr) && (size > 0U);
51 }
52};
53
60template <typename T, size_t Capacity> class WorkArray final
61{
62public:
63 WorkArray() = default;
64
65 static constexpr size_t get_capacity() noexcept
66 {
67 return Capacity;
68 }
69
70 [[nodiscard]] size_t get_used() const noexcept
71 {
72 return m_top;
73 }
74
75 [[nodiscard]] size_t get_remaining() const noexcept
76 {
77 return Capacity - get_used();
78 }
79
80 [[nodiscard]] T* data() noexcept
81 {
82 return m_data.data();
83 }
84
85 [[nodiscard]] const T* data() const noexcept
86 {
87 return m_data.data();
88 }
89
93 void reset() noexcept
94 {
95 m_top = 0U;
96 }
97
101 [[nodiscard]] size_t get_marker() const noexcept
102 {
103 return m_top;
104 }
105
109 WorkArrayStatus restore(size_t marker) noexcept
110 {
111 if (marker > m_top)
112 {
114 }
115 m_top = marker;
117 }
118
126 WorkArrayStatus allocate(size_t len, WorkBlock<T>& out) noexcept
127 {
128 out = {};
129 if ((len == 0U) || (len > Capacity))
130 {
132 }
133 if ((m_top + len) > Capacity)
134 {
136 }
137
138 out.offset = m_top;
139 out.data = &m_data[m_top];
140 out.size = len;
141 m_top += len;
143 }
144
152 WorkArrayStatus deallocate(T* ptr, size_t len) noexcept
153 {
154 if ((ptr == nullptr) || (len == 0U) || (len > Capacity))
155 {
157 }
158
159 T* const begin = m_data.data();
160 T* const end = m_data.data() + Capacity;
161 if ((ptr < begin) || (ptr >= end))
162 {
164 }
165
166 const size_t start = static_cast<size_t>(ptr - begin);
167 if ((start + len) > Capacity)
168 {
170 }
171
172 // Strict LIFO: must free from the current top of stack.
173 if ((start + len) != m_top)
174 {
176 }
177
178 m_top = start;
180 }
181
186 {
187 return deallocate(block.data, block.size);
188 }
189
190private:
191 std::array<T, Capacity> m_data = {};
192 size_t m_top = 0U;
193};
194
201template <typename T, size_t Capacity> class WorkFrame final
202{
203public:
204 explicit WorkFrame(WorkArray<T, Capacity>& work) noexcept
205 : m_work(work)
206 , m_marker(work.get_marker())
207 {
208 }
209
210 WorkFrame(const WorkFrame&) = delete;
211 WorkFrame& operator=(const WorkFrame&) = delete;
212 WorkFrame(WorkFrame&&) = delete;
213 WorkFrame& operator=(WorkFrame&&) = delete;
214
215 ~WorkFrame() noexcept
216 {
217 (void)m_work.restore(m_marker);
218 }
219
220 [[nodiscard]] size_t get_marker() const noexcept
221 {
222 return m_marker;
223 }
224
225 WorkArrayStatus allocate(size_t len, WorkBlock<T>& out) noexcept
226 {
227 return m_work.allocate(len, out);
228 }
229
230private:
232 size_t m_marker;
233};
234
239} // namespace fsb
240
241#endif // FSB_WORK_H
242
Fixed-capacity allocator for temporary work buffers.
Definition fsb_work.h:61
WorkArrayStatus deallocate(T *ptr, size_t len) noexcept
Deallocate a work block previously returned by allocate().
Definition fsb_work.h:152
size_t get_marker() const noexcept
Get a marker representing the current top of stack.
Definition fsb_work.h:101
void reset() noexcept
Reset allocator state (frees all allocations).
Definition fsb_work.h:93
WorkArrayStatus restore(size_t marker) noexcept
Restore the allocator to a previous marker (LIFO bulk free).
Definition fsb_work.h:109
WorkArrayStatus allocate(size_t len, WorkBlock< T > &out) noexcept
Allocate a contiguous work block of len elements.
Definition fsb_work.h:126
WorkArrayStatus deallocate(const WorkBlock< T > &block) noexcept
Deallocate a work block.
Definition fsb_work.h:185
RAII helper that restores a WorkArray to its entry marker.
Definition fsb_work.h:202
@ FULL
Operation failed, buffer is full.
@ SUCCESS
Successful operation.
WorkArrayStatus
Definition fsb_work.h:28
@ OUT_OF_ORDER
Attempted to free memory out of LIFO order.
@ FULL
Not enough space available.
@ SUCCESS
Successful operation.
@ INVALID_ARGUMENT
Invalid argument (null pointer, out of range, size==0, etc.)
A view describing an allocated work block.
Definition fsb_work.h:43