37#include <seastar/util/modules.hh>
52template <
typename T,
size_t Capacity>
58 maybe_storage()
noexcept {}
61 maybe_storage _storage[Capacity];
63 static size_t mask(
size_t idx) {
return idx % Capacity; }
64 T* obj(
size_t idx) {
return &_storage[mask(idx)].data; }
65 const T* obj(
size_t idx)
const {
return &_storage[mask(idx)].data; }
67 static_assert((Capacity & (Capacity - 1)) == 0,
"capacity must be a power of two");
68 static_assert(std::is_nothrow_move_constructible_v<T> && std::is_nothrow_move_assignable_v<T>,
69 "circular_buffer_fixed_capacity only supports nothrow-move value types");
71 using size_type = size_t;
74 using const_reference =
const T&;
75 using const_pointer =
const T*;
76 using difference_type = ssize_t;
78 template <
typename ValueType>
80 using holder = std::conditional_t<std::is_const_v<ValueType>,
const maybe_storage, maybe_storage>;
84 cbiterator(holder* start,
size_t idx) noexcept : _start(start), _idx(idx) {}
86 using iterator_category = std::random_access_iterator_tag;
87 using value_type = ValueType;
88 using difference_type = ssize_t;
89 using pointer = ValueType*;
90 using reference = ValueType&;
93 ValueType& operator*()
const {
return _start[mask(_idx)].data; }
94 ValueType* operator->()
const {
return &operator*(); }
117 cbiterator operator+(difference_type n)
const {
123 cbiterator operator-(difference_type n)
const {
134 bool operator==(
const cbiterator& rhs)
const {
135 return _idx == rhs._idx;
137 bool operator!=(
const cbiterator& rhs)
const {
138 return _idx != rhs._idx;
141 return ssize_t(_idx - rhs._idx) < 0;
144 return ssize_t(_idx - rhs._idx) > 0;
146 bool operator<=(
const cbiterator& rhs)
const {
147 return ssize_t(_idx - rhs._idx) <= 0;
149 bool operator>=(
const cbiterator& rhs)
const {
150 return ssize_t(_idx - rhs._idx) >= 0;
152 difference_type operator-(
const cbiterator& rhs)
const {
153 return _idx - rhs._idx;
165 void push_front(
const T& data);
166 void push_front(T&& data);
167 template <
typename... A>
168 T& emplace_front(A&&... args);
169 void push_back(
const T& data);
170 void push_back(T&& data);
171 template <
typename... A>
172 T& emplace_back(A&&... args);
179 size_t capacity()
const;
180 T& operator[](
size_t idx);
185 const_iterator begin()
const {
186 return const_iterator(_storage, _begin);
189 return iterator(_storage, _end);
191 const_iterator end()
const {
192 return const_iterator(_storage, _end);
194 const_iterator cbegin()
const {
195 return const_iterator(_storage, _begin);
197 const_iterator cend()
const {
198 return const_iterator(_storage, _end);
200 iterator erase(iterator first, iterator last);
203template <
typename T,
size_t Capacity>
206circular_buffer_fixed_capacity<T, Capacity>::empty()
const {
207 return _begin == _end;
210template <
typename T,
size_t Capacity>
213circular_buffer_fixed_capacity<T, Capacity>::size()
const {
214 return _end - _begin;
217template <
typename T,
size_t Capacity>
220circular_buffer_fixed_capacity<T, Capacity>::capacity()
const {
224template <
typename T,
size_t Capacity>
226circular_buffer_fixed_capacity<T, Capacity>::circular_buffer_fixed_capacity(circular_buffer_fixed_capacity&& x) noexcept
227 : _begin(x._begin), _end(x._end) {
228 std::uninitialized_move(x.begin(), x.end(), begin());
231template <
typename T,
size_t Capacity>
233circular_buffer_fixed_capacity<T, Capacity>&
234circular_buffer_fixed_capacity<T, Capacity>::operator=(circular_buffer_fixed_capacity&& x)
noexcept {
236 this->~circular_buffer_fixed_capacity();
237 new (
this) circular_buffer_fixed_capacity(std::move(x));
242template <
typename T,
size_t Capacity>
244circular_buffer_fixed_capacity<T, Capacity>::~circular_buffer_fixed_capacity() {
248template <
typename T,
size_t Capacity>
251circular_buffer_fixed_capacity<T, Capacity>::push_front(
const T& data) {
252 new (obj(_begin - 1)) T(data);
256template <
typename T,
size_t Capacity>
259circular_buffer_fixed_capacity<T, Capacity>::push_front(T&& data) {
260 new (obj(_begin - 1)) T(std::move(data));
264template <
typename T,
size_t Capacity>
265template <
typename... Args>
268circular_buffer_fixed_capacity<T, Capacity>::emplace_front(Args&&... args) {
269 auto p =
new (obj(_begin - 1)) T(std::forward<Args>(args)...);
274template <
typename T,
size_t Capacity>
277circular_buffer_fixed_capacity<T, Capacity>::push_back(
const T& data) {
278 new (obj(_end)) T(data);
282template <
typename T,
size_t Capacity>
285circular_buffer_fixed_capacity<T, Capacity>::push_back(T&& data) {
286 new (obj(_end)) T(std::move(data));
290template <
typename T,
size_t Capacity>
291template <
typename... Args>
294circular_buffer_fixed_capacity<T, Capacity>::emplace_back(Args&&... args) {
295 auto p =
new (obj(_end)) T(std::forward<Args>(args)...);
300template <
typename T,
size_t Capacity>
303circular_buffer_fixed_capacity<T, Capacity>::front() {
307template <
typename T,
size_t Capacity>
310circular_buffer_fixed_capacity<T, Capacity>::back() {
311 return *obj(_end - 1);
314template <
typename T,
size_t Capacity>
317circular_buffer_fixed_capacity<T, Capacity>::pop_front() {
322template <
typename T,
size_t Capacity>
325circular_buffer_fixed_capacity<T, Capacity>::pop_back() {
330template <
typename T,
size_t Capacity>
333circular_buffer_fixed_capacity<T, Capacity>::operator[](
size_t idx) {
334 return *obj(_begin + idx);
337template <
typename T,
size_t Capacity>
339typename circular_buffer_fixed_capacity<T, Capacity>::iterator
340circular_buffer_fixed_capacity<T, Capacity>::erase(iterator first, iterator last) {
341 static_assert(std::is_nothrow_move_assignable_v<T>,
"erase() assumes move assignment does not throw");
347 if (std::distance(begin(), first) < std::distance(last, end())) {
348 auto new_start = std::move_backward(begin(), first, last);
350 while (i < new_start) {
353 _begin = new_start.idx;
356 auto new_end = std::move(last, end(), first);
367template <
typename T,
size_t Capacity>
370circular_buffer_fixed_capacity<T, Capacity>::clear() {
371 for (
auto& obj : *
this) {
Definition: circular_buffer_fixed_capacity.hh:79
Definition: circular_buffer_fixed_capacity.hh:53
Seastar API namespace.
Definition: abort_on_ebadf.hh:26