37 template <
typename T >
38 class static_circular_buffer_iterator;
40 template < std::
size_t N >
44 return std::atomic_uint8_t{};
46 return std::atomic_uint16_t{};
48 return std::atomic_uint32_t{};
50 return std::atomic_uint64_t{};
58 template < std::
size_t N >
63 using index_type = decltype( _select_index_type< N >() );
128 template < std::
size_t N >
131 static_assert(
N && !(
N & (
N - 1 ) ),
"N must be power of two" );
169 return static_cast< size_type >( to_ - from_ );
192 template <
typename T, std::
size_t N >
195 static constexpr
bool is_power_of_two =
N && !(
N & (
N - 1 ) );
196 if constexpr ( is_power_of_two )
209 template < typename T, std::size_t N, typename Strategy = decltype( _select_strategy< T, N >() ) >
219 "static_circular_buffer: N must be less than index_type max value" );
232 copy_range_back( other );
237 move_range_back( other );
245 if (
this == &other )
248 copy_range_back( other );
256 if (
this == &other )
259 move_range_back( other );
270 storage_.data() + strategy_.front_idx() };
279 storage_.data() + strategy_.front_idx() };
283 [[nodiscard]] std::reverse_iterator< iterator >
rbegin() noexcept
285 return std::make_reverse_iterator( end() );
289 [[nodiscard]] std::reverse_iterator< const_iterator >
rbegin() const noexcept
291 return std::make_reverse_iterator( end() );
297 return storage_[
static_cast< size_type >( strategy_.front_idx() )];
303 return storage_[
static_cast< size_type >( strategy_.front_idx() )];
309 T item = std::move( front() );
317 auto n =
static_cast< size_type >( std::size( buffer ) );
318 auto iter = std::begin( buffer );
319 auto idx =
static_cast< size_type >( strategy_.front_idx() );
320 auto* p = storage_.data() + idx;
322 if ( capacity >= n ) {
323 std::move( p, p + n, iter );
325 iter = std::move( p, p + capacity, iter );
326 std::move( storage_.data(), storage_.data() + idx + n - capacity, iter );
328 strategy_.incr_front( n );
334 storage_.delete_item(
static_cast< size_type >( strategy_.front_idx() ) );
335 strategy_.incr_front();
341 auto idx =
static_cast< size_type >( strategy_.front_idx() );
343 if ( capacity >= n ) {
344 storage_.delete_n( idx, n );
346 storage_.delete_n( idx, capacity );
347 storage_.delete_n( 0, n - capacity );
349 strategy_.incr_front( n );
358 storage_.data() + strategy_.back_idx() };
367 storage_.data() + strategy_.back_idx() };
371 [[nodiscard]] std::reverse_iterator< iterator >
rend() noexcept
373 return std::make_reverse_iterator( begin() );
377 [[nodiscard]] std::reverse_iterator< const_iterator >
rend() const noexcept
379 return std::make_reverse_iterator( begin() );
385 return storage_[
static_cast< size_type >( strategy_.last_idx() )];
391 return storage_[
static_cast< size_type >( strategy_.last_idx() )];
397 emplace_back( std::move( item ) );
401 template <
typename... Args >
404 T& ref = storage_.emplace_item(
405 static_cast< size_type >( strategy_.back_idx() ),
406 std::forward< Args >(
args )... );
407 strategy_.incr_back();
414 auto idx =
static_cast< size_type >( strategy_.back_idx() );
416 auto n = std::size(
range );
417 auto iter = std::begin(
range );
418 if ( capacity >= n ) {
419 storage_.copy_n( idx, n, iter );
421 iter = storage_.copy_n( idx, capacity, iter );
422 storage_.copy_n( 0, n - capacity, iter );
424 strategy_.incr_back(
static_cast< size_type >( n ) );
430 auto idx =
static_cast< size_type >( strategy_.back_idx() );
432 auto n = std::size(
range );
433 auto iter = std::begin(
range );
434 if ( capacity >= n ) {
435 storage_.move_n( idx, n, iter );
437 iter = storage_.move_n( idx, capacity, iter );
438 storage_.move_n( 0, n - capacity, iter );
440 strategy_.incr_back(
static_cast< size_type >( n ) );
452 return static_cast< size_type >( strategy_.size() );
456 [[nodiscard]]
bool empty() const noexcept
458 return strategy_.empty();
462 [[nodiscard]]
bool full() const noexcept
464 return strategy_.full();
483 template <
typename U >
487 template <
typename T, std::
size_t N >
491 return std::lexicographical_compare_three_way( lh.
begin(), lh.
end(), rh.
begin(), rh.
end() );
494 template <
typename T, std::
size_t N >
498 auto size = lh.
size();
499 if ( size != rh.
size() )
505 template <
typename T, std::
size_t N >
509 return !( lh == rh );
512 #ifdef EMLABCPP_USE_OSTREAM
514 template <
typename T, std::
size_t N >
515 std::ostream&
operator<<( std::ostream& os, static_circular_buffer< T, N >
const& cb )
517 return os <<
view{ cb };
523 template <
typename T >
524 struct std::iterator_traits<
emlabcpp::static_circular_buffer_iterator< T > >
537 template <
typename T >
542 static constexpr
bool is_const = std::is_const_v< T >;
544 using reference = std::conditional_t< is_const, value_type const&, value_type& >;
547 typename std::iterator_traits< static_circular_buffer_iterator< T > >
::difference_type;
587 p_ -= ( end_ - beg_ );
594 if ( p_ == ( beg_ - 1 ) )
603 p_ += ( end_ - beg_ );
609 return p_ <=> other.p_;
614 return p_ == other.p_;
Definition: static_circular_buffer.h:540
static constexpr bool is_const
Definition: static_circular_buffer.h:542
static_circular_buffer_iterator(static_circular_buffer_iterator const &) noexcept=default
static_circular_buffer_iterator(T *beg, T *end, T *p) noexcept
Definition: static_circular_buffer.h:549
static_circular_buffer_iterator & operator--() noexcept
Definition: static_circular_buffer.h:591
value_type const & const_reference
Definition: static_circular_buffer.h:545
reference operator*() const noexcept
Definition: static_circular_buffer.h:570
typename std::iterator_traits< static_circular_buffer_iterator< T > >::difference_type difference_type
Definition: static_circular_buffer.h:547
static_circular_buffer_iterator & operator+=(difference_type v) noexcept
Definition: static_circular_buffer.h:583
static_circular_buffer_iterator(static_circular_buffer_iterator &&) noexcept=default
bool operator==(static_circular_buffer_iterator const &other) const noexcept
Definition: static_circular_buffer.h:612
static_circular_buffer_iterator & operator++() noexcept
Definition: static_circular_buffer.h:575
std::conditional_t< is_const, value_type const &, value_type & > reference
Definition: static_circular_buffer.h:544
T value_type
Definition: static_circular_buffer.h:543
static_circular_buffer_iterator & operator-=(difference_type v) noexcept
Definition: static_circular_buffer.h:599
auto operator<=>(static_circular_buffer_iterator const &other) const noexcept
Definition: static_circular_buffer.h:607
bounded< std::size_t, max_size, max_size > size_type
Definition: serializer.h:74
static constexpr std::size_t max_size
Definition: serializer.h:73
std::variant< int64_t, float, bool, string_buffer > value_type
Definition: base.h:51
MIT License.
Definition: impl.h:31
view(Container &cont) -> view< iterator_of_t< Container > >
The container deduction guide uses iterator_of_t.
constexpr bool equal(LhContainer &&lh, RhContainer &&rh, BinaryPredicateCallable &&f=std::equal_to< void >{})
Returns true if containers 'lh' and 'rh' has same size and calls to predicate f - f(lh[i],...
Definition: algorithm.h:356
Args const & args
Definition: min_max.h:83
constexpr Derived max(vec_point_base< Derived, N > const &a, vec_point_base< Derived, N > const &b)
Definition: vec_point_base.h:229
auto _select_strategy()
Definition: static_circular_buffer.h:193
constexpr auto _select_index_type()
Definition: static_circular_buffer.h:41
constexpr view< iterators::numeric_iterator< Numeric > > range(Numeric from, Numeric to)
Builds numeric view over interval [from, to)
Definition: range.h:34
auto operator<=>(static_circular_buffer< T, N > const &lh, static_circular_buffer< T, N > const &rh)
Definition: static_circular_buffer.h:489
constexpr bool operator!=(pose const &x, pose const &y)
negation of operator== between poses
Definition: pose.h:99
std::ostream & operator<<(std::ostream &os, string_buffer< N > const &sb)
Definition: string_buffer.h:168
N
Definition: static_storage.h:157
constexpr bool operator==(pose const &x, pose const &y)
compares poses on their position and orientation
Definition: pose.h:93
generic_iterator simplifies custom iterator implementation using CRTP.
Definition: iterator.h:62
Strategy for managing indices in circular buffer via overflowing indices.
Definition: static_circular_buffer.h:130
bool full() const noexcept
Definition: static_circular_buffer.h:177
void incr_front() noexcept
Definition: static_circular_buffer.h:137
void incr_front(size_type n) noexcept
Definition: static_circular_buffer.h:142
auto back_idx() const noexcept
Definition: static_circular_buffer.h:162
auto size() const noexcept
Definition: static_circular_buffer.h:167
typename index_type::value_type size_type
Definition: static_circular_buffer.h:135
index_type last_idx() const noexcept
Definition: static_circular_buffer.h:182
void incr_back() noexcept
Definition: static_circular_buffer.h:152
bool empty() const noexcept
Definition: static_circular_buffer.h:172
auto front_idx() const noexcept
Definition: static_circular_buffer.h:147
void incr_back(size_type n) noexcept
Definition: static_circular_buffer.h:157
static constexpr std::size_t max_size
Definition: static_circular_buffer.h:132
decltype(_select_index_type< N >()) index_type
Definition: static_circular_buffer.h:134
Strategy for managing indices in circular buffer via empty slot.
Definition: static_circular_buffer.h:60
size_type size() const noexcept
Definition: static_circular_buffer.h:96
auto back_idx() const noexcept
Definition: static_circular_buffer.h:91
static constexpr std::size_t max_size
Definition: static_circular_buffer.h:61
bool empty() const noexcept
Definition: static_circular_buffer.h:103
decltype(_select_index_type< N >()) index_type
Definition: static_circular_buffer.h:63
typename index_type::value_type size_type
Definition: static_circular_buffer.h:64
void incr_front() noexcept
Definition: static_circular_buffer.h:66
bool full() const noexcept
Definition: static_circular_buffer.h:108
index_type last_idx() const noexcept
Definition: static_circular_buffer.h:113
auto front_idx() const noexcept
Definition: static_circular_buffer.h:76
void incr_back(size_type n) noexcept
Definition: static_circular_buffer.h:86
void incr_back() noexcept
Definition: static_circular_buffer.h:81
void incr_front(size_type n) noexcept
Definition: static_circular_buffer.h:71
Class implementing circular buffer of any type for up to N elements.
Definition: static_circular_buffer.h:211
reference back() noexcept
Reference to last element.
Definition: static_circular_buffer.h:383
std::reverse_iterator< const_iterator > rbegin() const noexcept
Reverse iterator to last element.
Definition: static_circular_buffer.h:289
const_iterator begin() const noexcept
Iterator to first element.
Definition: static_circular_buffer.h:274
iterator end() noexcept
Iterator to one-past-last element.
Definition: static_circular_buffer.h:353
~static_circular_buffer()
Destructor destructs all contained elements.
Definition: static_circular_buffer.h:474
const_reference back() const noexcept
Reference to last element.
Definition: static_circular_buffer.h:389
void take_front(auto &&buffer)
Removes and moves first n elements into provided buffer, is safe in SPSC scenario.
Definition: static_circular_buffer.h:315
T value_type
Definition: static_circular_buffer.h:221
iterator begin() noexcept
Iterator to first element.
Definition: static_circular_buffer.h:265
std::reverse_iterator< iterator > rend() noexcept
Reverse iterator to one-before-first element.
Definition: static_circular_buffer.h:371
static_circular_buffer(static_circular_buffer &&other) noexcept
Definition: static_circular_buffer.h:235
T & reference
Definition: static_circular_buffer.h:222
std::reverse_iterator< iterator > rbegin() noexcept
Reverse iterator to last element.
Definition: static_circular_buffer.h:283
void clear()
Clears the buffer by destructing all contained elements.
Definition: static_circular_buffer.h:468
T & emplace_back(Args &&... args)
Inserts item constructed with args... at the back, is safe in SPSC scenario.
Definition: static_circular_buffer.h:402
void pop_front()
Removes first element, is safe in SPSC scenario.
Definition: static_circular_buffer.h:332
constexpr size_type capacity() const noexcept
Returns maximum capacity of the buffer.
Definition: static_circular_buffer.h:444
typename Strategy::size_type size_type
Definition: static_circular_buffer.h:215
static_circular_buffer & operator=(static_circular_buffer const &other)
Clears the buffer by destructing all contained elements and copies from other buffer.
Definition: static_circular_buffer.h:243
bool empty() const noexcept
Returns whether the buffer is empty.
Definition: static_circular_buffer.h:456
void push_back(T item)
Inserts item at the back, is safe in SPSC scenario.
Definition: static_circular_buffer.h:395
void pop_front(size_type n)
Removes first n elements, is safe in SPSC scenario.
Definition: static_circular_buffer.h:339
const_reference front() const noexcept
Reference to first element.
Definition: static_circular_buffer.h:301
std::reverse_iterator< const_iterator > rend() const noexcept
Reverse iterator to one-before-first element.
Definition: static_circular_buffer.h:377
T const & const_reference
Definition: static_circular_buffer.h:223
const_iterator end() const noexcept
Iterator to one-past-last element.
Definition: static_circular_buffer.h:362
bool full() const noexcept
Returns whether the buffer is full.
Definition: static_circular_buffer.h:462
reference front() noexcept
Reference to first element.
Definition: static_circular_buffer.h:295
T take_front()
Removes and returns first element, is safe in SPSC scenario.
Definition: static_circular_buffer.h:307
size_type size() const
Returns current size of the buffer.
Definition: static_circular_buffer.h:450
static_circular_buffer() noexcept=default
Default constructed circular buffer is empty.
typename Strategy::index_type index_type
Definition: static_circular_buffer.h:214
void move_range_back(auto &&range)
Inserts range by move at the back, is safe in SPSC scenario.
Definition: static_circular_buffer.h:428
void copy_range_back(auto &&range)
Inserts range by copy at the back, is safe in SPSC scenario.
Definition: static_circular_buffer.h:412
static_circular_buffer & operator=(static_circular_buffer &&other) noexcept
Clears the buffer by destructing all contained elements and moves from other buffer.
Definition: static_circular_buffer.h:254
T value_type
Definition: static_circular_buffer.h:526
std::bidirectional_iterator_tag iterator_category
Definition: static_circular_buffer.h:531
std::make_signed_t< std::size_t > difference_type
Definition: static_circular_buffer.h:527
value_type * pointer
Definition: static_circular_buffer.h:528
value_type & reference
Definition: static_circular_buffer.h:530
value_type const * const_pointer
Definition: static_circular_buffer.h:529