| 163 | // Uses vector_inlined internally — inline when N > 0, heap when N == 0. |
| 164 | template <typename T, fl::size N = 0> |
| 165 | class circular_buffer { |
| 166 | public: |
| 167 | // Default constructor — pre-sizes to N (useful when N > 0). |
| 168 | circular_buffer() FL_NOEXCEPT { |
| 169 | mStorage.resize(N); |
| 170 | mCore.assign(mStorage.data(), N); |
| 171 | } |
| 172 | |
| 173 | // PMR-aware constructor. |
| 174 | explicit circular_buffer(memory_resource* resource) |
| 175 | : mStorage(resource) { |
| 176 | mStorage.resize(N); |
| 177 | mCore.assign(mStorage.data(), N); |
| 178 | } |
| 179 | |
| 180 | // Capacity constructor — for dynamic (N==0) or overriding static size. |
| 181 | explicit circular_buffer(fl::size capacity) { |
| 182 | mStorage.resize(capacity); |
| 183 | mCore.assign(mStorage.data(), capacity); |
| 184 | } |
| 185 | |
| 186 | // Capacity constructor with PMR. |
| 187 | circular_buffer(fl::size capacity, memory_resource* resource) |
| 188 | : mStorage(resource) { |
| 189 | mStorage.resize(capacity); |
| 190 | mCore.assign(mStorage.data(), capacity); |
| 191 | } |
| 192 | |
| 193 | circular_buffer(const circular_buffer& other) FL_NOEXCEPT |
| 194 | : mStorage(other.mStorage), |
| 195 | mCore(mStorage.data(), mStorage.size()) { |
| 196 | mCore.setHead(other.mCore.head()); |
| 197 | mCore.setTail(other.mCore.tail()); |
| 198 | mCore.setFull(other.mCore.isFull()); |
| 199 | } |
| 200 | |
| 201 | circular_buffer(circular_buffer&& other) FL_NOEXCEPT |
| 202 | : mStorage(fl::move(other.mStorage)), |
| 203 | mCore(mStorage.data(), mStorage.size()) { |
| 204 | mCore.setHead(other.mCore.head()); |
| 205 | mCore.setTail(other.mCore.tail()); |
| 206 | mCore.setFull(other.mCore.isFull()); |
| 207 | other.mCore.assign(nullptr, 0); |
| 208 | } |
| 209 | |
| 210 | circular_buffer& operator=(const circular_buffer& other) FL_NOEXCEPT { |
| 211 | if (this != &other) { |
| 212 | mStorage = other.mStorage; |
| 213 | mCore.assign(mStorage.data(), mStorage.size()); |
| 214 | mCore.setHead(other.mCore.head()); |
| 215 | mCore.setTail(other.mCore.tail()); |
| 216 | mCore.setFull(other.mCore.isFull()); |
| 217 | } |
| 218 | return *this; |
| 219 | } |
| 220 | |
| 221 | circular_buffer& operator=(circular_buffer&& other) FL_NOEXCEPT { |
| 222 | if (this != &other) { |