16 template<
typename T,
size_t N>
21 template<
bool IsConst>
22 class Iterator
final {
24 using difference_type = ptrdiff_t;
26 using pointer =
typename std::conditional_t<IsConst, const T*, T*>;
27 using reference =
typename std::conditional_t<IsConst, const T&, T&>;
28 using iterator_category = std::random_access_iterator_tag;
30 constexpr Iterator(pointer data, ptrdiff_t offset) :
37 constexpr operator Iterator<true>()
const
39 return Iterator<true>{data_, offset_};
44 constexpr Iterator& operator++()
46 offset_ = (offset_ + 1) %
N;
52 return data_[offset_];
57 constexpr friend auto operator<=>(
const Iterator&,
const Iterator&) =
default;
61 constexpr pointer operator->()
const
63 return &data_[offset_];
68 constexpr Iterator operator++(
int)
77 constexpr Iterator& operator--()
79 offset_ = offset_ == 0 ?
N - 1 : offset_ - 1;
83 constexpr Iterator operator--(
int)
92 constexpr Iterator& operator+=(difference_type i)
94 offset_ = (offset_ + i) %
N;
98 constexpr Iterator
operator+(difference_type i)
const
100 Iterator copy{*
this};
105 constexpr Iterator& operator-=(difference_type i)
107 difference_type im = (i %
N);
110 offset_ =
N - (im - offset_);
113 offset_ = offset_ - im;
119 constexpr Iterator
operator-(difference_type i)
const
121 Iterator copy{*
this};
126 constexpr difference_type
operator-(
const Iterator& other)
const
128 return offset_ - other.offset_;
131 constexpr reference operator[](difference_type pos)
const
133 return data_[(offset_ + pos) %
N];
137 pointer data_ =
nullptr;
138 ptrdiff_t offset_ = 0;
161 std::destroy(this->begin(), this->end());
168 return at(*
this,
pos);
172 return at(*
this,
pos);
176 return at(*
this,
pos);
180 return at(*
this,
pos);
202 return iterator_at(*
this, begin_offset_);
206 return iterator_at(*
this, begin_offset_);
214 return iterator_at(*
this, end_offset_);
218 return iterator_at(*
this, end_offset_);
252 return begin_offset_ == end_offset_;
256 return end_offset_ >= begin_offset_ ? end_offset_ - begin_offset_ : (
N - begin_offset_) + end_offset_;
271 std::destroy(this->begin(), this->end());
276 template<
typename...
Args>
277 requires std::constructible_from<
T,
Args&&...>
282 if (
new_end == begin_offset_) {
290 std::destroy_at(&front());
291 begin_offset_ = (begin_offset_ + 1) %
N;
295 object_bytes*
const ptr = raw_storage_bytes_.data() + end_offset_;
310 emplace_back(std::move(value));
316 throw std::runtime_error{
"tried to remove a range of elements in the middle of a circular buffer (can currently only erase elements from end of circular buffer)"};
320 end_offset_ -= std::distance(
first,
last);
327 std::optional<T>
rv = std::nullopt;
333 rv.emplace(std::move(back()));
334 end_offset_ = end_offset_ == 0 ?
static_cast<ptrdiff_t>(
N) - 1 : end_offset_ - 1;
342 throw std::runtime_error{
"tried to call Circular_buffer::pop_back on an empty circular buffer"};
345 T rv{std::move(back())};
346 end_offset_ = end_offset_ == 0 ?
static_cast<ptrdiff_t>(
N) - 1 : end_offset_ - 1;
351 template<
typename CircularBuf>
354 throw std::out_of_range{
"tried to access a circular buffer element outside of its range"};
359 template<
typename CircularBuf>
361 using Value = std::conditional_t<std::is_const_v<CircularBuf>,
const T,
T>;
363 static_assert(
alignof(
Value) ==
alignof(
typename decltype(
buf.raw_storage_bytes_)::value_type));
364 static_assert(
sizeof(
Value) ==
sizeof(
typename decltype(
buf.raw_storage_bytes_)::value_type));
365 Value*
ptr = std::launder(
reinterpret_cast<Value*
>(
buf.raw_storage_bytes_.data()));
367 return Iterator{
ptr,
pos};
391 class alignas(T) object_bytes { std::byte data[
sizeof(
T)]; };
392 std::array<object_bytes, N> raw_storage_bytes_{};
Definition circular_buffer.h:18
Iterator< false > iterator
Definition circular_buffer.h:149
const T & const_reference
Definition circular_buffer.h:148
constexpr void push_back(const T &value)
Definition circular_buffer.h:303
T value_type
Definition circular_buffer.h:145
constexpr const_iterator cend() const
Definition circular_buffer.h:221
constexpr bool empty() const
Definition circular_buffer.h:251
constexpr const_reverse_iterator rend() const
Definition circular_buffer.h:237
constexpr reference at(size_type pos)
Definition circular_buffer.h:167
constexpr iterator erase(iterator first, iterator last)
Definition circular_buffer.h:313
constexpr size_type max_size() const
Definition circular_buffer.h:259
constexpr const_reference back() const
Definition circular_buffer.h:195
constexpr iterator end()
Definition circular_buffer.h:217
constexpr const_iterator cbegin() const
Definition circular_buffer.h:209
Iterator< true > const_iterator
Definition circular_buffer.h:150
constexpr reverse_iterator rend()
Definition circular_buffer.h:241
constexpr const_iterator end() const
Definition circular_buffer.h:213
constexpr size_type size() const
Definition circular_buffer.h:255
CircularBuffer(CircularBuffer &&) noexcept=delete
constexpr iterator begin()
Definition circular_buffer.h:205
constexpr reference back()
Definition circular_buffer.h:191
constexpr T pop_back()
Definition circular_buffer.h:339
constexpr void push_back(T &&value)
Definition circular_buffer.h:308
size_t size_type
Definition circular_buffer.h:146
constexpr reference operator[](size_type pos)
Definition circular_buffer.h:175
constexpr const_reference front() const
Definition circular_buffer.h:187
constexpr void clear()
Definition circular_buffer.h:269
constexpr reverse_iterator rbegin()
Definition circular_buffer.h:229
CircularBuffer(const CircularBuffer &)=delete
constexpr const_reverse_iterator crend() const
Definition circular_buffer.h:245
T & reference
Definition circular_buffer.h:147
std::reverse_iterator< iterator > reverse_iterator
Definition circular_buffer.h:151
constexpr const_iterator begin() const
Definition circular_buffer.h:201
constexpr const_reverse_iterator rbegin() const
Definition circular_buffer.h:225
constexpr const_reverse_iterator crbegin() const
Definition circular_buffer.h:233
constexpr std::optional< T > try_pop_back()
Definition circular_buffer.h:325
constexpr const_reference at(size_type pos) const
Definition circular_buffer.h:171
constexpr reference front()
Definition circular_buffer.h:183
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition circular_buffer.h:152
constexpr const_reference operator[](size_type pos) const
Definition circular_buffer.h:179
constexpr T & emplace_back(Args &&... args)
Definition circular_buffer.h:278
Definition custom_decoration_generator.h:5
constexpr std::ranges::range_reference_t< R > at(R &&r, std::ranges::range_size_t< R > pos)
Definition algorithms.h:67
constexpr std::common_type_t< Angle< Rep1, Units1 >, Angle< Rep2, Units2 > > operator+(const Angle< Rep1, Units1 > &lhs, const Angle< Rep2, Units2 > &rhs)
Definition angle.h:99
constexpr U to(T &&value)
Definition conversion.h:56
constexpr auto operator<=>(const Angle< Rep1, Units1 > &lhs, const Angle< Rep2, Units2 > &rhs)
Definition angle.h:142
constexpr std::common_type_t< Angle< Rep1, Units1 >, Angle< Rep2, Units2 > > operator-(const Angle< Rep1, Units1 > &lhs, const Angle< Rep2, Units2 > &rhs)
Definition angle.h:114