31 #ifndef SEASTAR_MODULE
32 #include <type_traits>
36 #include <seastar/util/modules.hh>
51 template <
typename T,
size_t Capacity>
57 maybe_storage() noexcept {}
60 maybe_storage _storage[Capacity];
62 static size_t mask(
size_t idx) {
return idx % Capacity; }
63 T* obj(
size_t idx) {
return &_storage[mask(idx)].data; }
64 const T* obj(
size_t idx)
const {
return &_storage[mask(idx)].data; }
66 static_assert((Capacity & (Capacity - 1)) == 0,
"capacity must be a power of two");
67 static_assert(std::is_nothrow_move_constructible_v<T> && std::is_nothrow_move_assignable_v<T>,
68 "circular_buffer_fixed_capacity only supports nothrow-move value types");
70 using size_type = size_t;
73 using const_reference =
const T&;
74 using const_pointer =
const T*;
75 using difference_type = ssize_t;
77 template <
typename ValueType>
79 using holder = std::conditional_t<std::is_const_v<ValueType>,
const maybe_storage, maybe_storage>;
83 cbiterator(holder* start,
size_t idx) noexcept : _start(start), _idx(idx) {}
85 using iterator_category = std::random_access_iterator_tag;
86 using value_type = ValueType;
87 using difference_type = ssize_t;
88 using pointer = ValueType*;
89 using reference = ValueType&;
92 ValueType& operator*()
const {
return _start[mask(_idx)].data; }
93 ValueType* operator->()
const {
return &operator*(); }
116 cbiterator operator+(difference_type n)
const {
122 cbiterator operator-(difference_type n)
const {
133 bool operator==(
const cbiterator& rhs)
const {
134 return _idx == rhs._idx;
136 bool operator!=(
const cbiterator& rhs)
const {
137 return _idx != rhs._idx;
140 return ssize_t(_idx - rhs._idx) < 0;
143 return ssize_t(_idx - rhs._idx) > 0;
145 bool operator<=(
const cbiterator& rhs)
const {
146 return ssize_t(_idx - rhs._idx) <= 0;
148 bool operator>=(
const cbiterator& rhs)
const {
149 return ssize_t(_idx - rhs._idx) >= 0;
151 difference_type operator-(
const cbiterator& rhs)
const {
152 return _idx - rhs._idx;
164 void push_front(
const T& data);
165 void push_front(T&& data);
166 template <
typename... A>
167 T& emplace_front(A&&... args);
168 void push_back(
const T& data);
169 void push_back(T&& data);
170 template <
typename... A>
171 T& emplace_back(A&&... args);
178 size_t capacity()
const;
179 T& operator[](
size_t idx);
184 const_iterator begin()
const {
185 return const_iterator(_storage, _begin);
188 return iterator(_storage, _end);
190 const_iterator end()
const {
191 return const_iterator(_storage, _end);
193 const_iterator cbegin()
const {
194 return const_iterator(_storage, _begin);
196 const_iterator cend()
const {
197 return const_iterator(_storage, _end);
199 iterator erase(iterator first, iterator last);
202 template <
typename T,
size_t Capacity>
205 circular_buffer_fixed_capacity<T, Capacity>::empty()
const {
206 return _begin == _end;
209 template <
typename T,
size_t Capacity>
212 circular_buffer_fixed_capacity<T, Capacity>::size()
const {
213 return _end - _begin;
216 template <
typename T,
size_t Capacity>
219 circular_buffer_fixed_capacity<T, Capacity>::capacity()
const {
223 template <
typename T,
size_t Capacity>
225 circular_buffer_fixed_capacity<T, Capacity>::circular_buffer_fixed_capacity(circular_buffer_fixed_capacity&& x) noexcept
226 : _begin(x._begin), _end(x._end) {
229 for (
auto& obj : x) {
230 new (&*dest++) T(std::move(obj));
234 template <
typename T,
size_t Capacity>
236 circular_buffer_fixed_capacity<T, Capacity>&
237 circular_buffer_fixed_capacity<T, Capacity>::operator=(circular_buffer_fixed_capacity&& x) noexcept {
239 this->~circular_buffer_fixed_capacity();
240 new (
this) circular_buffer_fixed_capacity(std::move(x));
245 template <
typename T,
size_t Capacity>
247 circular_buffer_fixed_capacity<T, Capacity>::~circular_buffer_fixed_capacity() {
251 template <
typename T,
size_t Capacity>
254 circular_buffer_fixed_capacity<T, Capacity>::push_front(
const T& data) {
255 new (obj(_begin - 1)) T(data);
259 template <
typename T,
size_t Capacity>
262 circular_buffer_fixed_capacity<T, Capacity>::push_front(T&& data) {
263 new (obj(_begin - 1)) T(std::move(data));
267 template <
typename T,
size_t Capacity>
268 template <
typename... Args>
271 circular_buffer_fixed_capacity<T, Capacity>::emplace_front(Args&&... args) {
272 auto p =
new (obj(_begin - 1)) T(std::forward<Args>(args)...);
277 template <
typename T,
size_t Capacity>
280 circular_buffer_fixed_capacity<T, Capacity>::push_back(
const T& data) {
281 new (obj(_end)) T(data);
285 template <
typename T,
size_t Capacity>
288 circular_buffer_fixed_capacity<T, Capacity>::push_back(T&& data) {
289 new (obj(_end)) T(std::move(data));
293 template <
typename T,
size_t Capacity>
294 template <
typename... Args>
297 circular_buffer_fixed_capacity<T, Capacity>::emplace_back(Args&&... args) {
298 auto p =
new (obj(_end)) T(std::forward<Args>(args)...);
303 template <
typename T,
size_t Capacity>
306 circular_buffer_fixed_capacity<T, Capacity>::front() {
310 template <
typename T,
size_t Capacity>
313 circular_buffer_fixed_capacity<T, Capacity>::back() {
314 return *obj(_end - 1);
317 template <
typename T,
size_t Capacity>
320 circular_buffer_fixed_capacity<T, Capacity>::pop_front() {
325 template <
typename T,
size_t Capacity>
328 circular_buffer_fixed_capacity<T, Capacity>::pop_back() {
333 template <
typename T,
size_t Capacity>
336 circular_buffer_fixed_capacity<T, Capacity>::operator[](
size_t idx) {
337 return *obj(_begin + idx);
340 template <
typename T,
size_t Capacity>
342 typename circular_buffer_fixed_capacity<T, Capacity>::iterator
343 circular_buffer_fixed_capacity<T, Capacity>::erase(iterator first, iterator last) {
344 static_assert(std::is_nothrow_move_assignable_v<T>,
"erase() assumes move assignment does not throw");
350 if (std::distance(begin(), first) < std::distance(last, end())) {
351 auto new_start = std::move_backward(begin(), first, last);
353 while (i < new_start) {
356 _begin = new_start.idx;
359 auto new_end = std::move(last, end(), first);
370 template <
typename T,
size_t Capacity>
373 circular_buffer_fixed_capacity<T, Capacity>::clear() {
374 for (
auto& obj : *
this) {
Definition: circular_buffer_fixed_capacity.hh:78
Definition: circular_buffer_fixed_capacity.hh:52
Seastar API namespace.
Definition: abort_on_ebadf.hh:26