10#ifndef M5_UTILITY_CONTAINER_CIRCULAR_BUFFER_HPP 
   11#define M5_UTILITY_CONTAINER_CIRCULAR_BUFFER_HPP 
   17#if __cplusplus >= 201703L 
   20#include "../stl/optional.hpp" 
   35    using size_type       = size_t;
 
   37    using const_reference = 
const T&;
 
   38#if __cplusplus >= 201703L 
   45    using reverse_iterator       = std::reverse_iterator<iterator>;
 
   46    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
   53        assert(n != 0 && 
"Illegal size");
 
   61    template <
class InputIter>
 
   86    template <
class InputIterator>
 
   87    void assign(InputIterator first, InputIterator last)
 
   90        size_type sz = last - first;
 
   94        auto n = std::min(_cap, sz);
 
 
  105    void assign(size_type n, const_reference v)
 
  108        n = std::min(_cap, n);
 
 
  117    inline void assign(std::initializer_list<T> il)
 
  119        assign(il.begin(), il.end());
 
 
  131#if __cplusplus >= 201703L 
  132        return !
empty() ? std::make_optional(_buf[_tail]) : std::nullopt;
 
  134        return !
empty() ? m5::stl::make_optional(_buf[_tail]) : m5::stl::nullopt;
 
 
  143#if __cplusplus >= 201703L 
  144        return !
empty() ? std::make_optional(_buf[(_head - 1 + _cap) % _cap]) : std::nullopt;
 
  146        return !
empty() ? m5::stl::make_optional(_buf[(_head - 1 + _cap) % _cap]) : m5::stl::nullopt;
 
 
  155        assert(
size() > 0 && 
"container empty");
 
  156        assert(i < 
size() && 
"index overflow");
 
  157        return _buf[(_tail + i) % _cap];
 
 
  165#if __cplusplus >= 201703L 
  166        return (!
empty() && i < 
size()) ? std::make_optional(_buf[(_tail + i) % _cap]) : std::nullopt;
 
  168        return (!
empty() && i < 
size()) ? m5::stl::make_optional(_buf[(_tail + i) % _cap]) : m5::stl::nullopt;
 
 
  177    size_t read(value_type* outbuf, 
const size_t num)
 
  179        size_t sz = std::min(num, 
size());
 
  184        auto src    = &_buf[tail];
 
  185        size_t elms = std::min(_cap - tail, sz);
 
  187        std::copy(src, src + elms, outbuf);
 
  188        tail       = (tail + elms) % _cap;
 
  196            std::copy(src, src + elms, outbuf);
 
 
  211        return !
full() && (_head == _tail);
 
 
  226        return full() ? _cap : (_head >= _tail ? _head - _tail : _cap + _head - _tail);
 
 
  249        _tail       = (_tail - 1 + _cap) % _cap;
 
  252            _head = (_head - 1 + _cap) % _cap;
 
  254        _full = (_head == _tail);
 
 
  260        _head       = (_head + 1) % _cap;
 
  262            _tail = (_tail + 1) % _cap;
 
  264        _full = (_head == _tail);
 
 
  270            _tail = (_tail + 1) % _cap;
 
 
  278            _head = (_head - 1 + _cap) % _cap;
 
 
  293        std::fill(_buf.begin(), _buf.end(), v);
 
 
  303            std::swap(_buf, o._buf);
 
  304            std::swap(_cap, o._cap);
 
  305            std::swap(_head, o._head);
 
  306            std::swap(_tail, o._tail);
 
  307            std::swap(_full, o._full);
 
 
  315        using iterator_category = std::bidirectional_iterator_tag;
 
  316        using difference_type   = std::ptrdiff_t;
 
  317        using value_type        = CircularBuffer::value_type;
 
  318        using pointer           = CircularBuffer::value_type*;
 
  319        using reference         = CircularBuffer::reference;
 
  321        iterator() : _buffer(nullptr), _pos(0)
 
  324        iterator(CircularBuffer* buf, 
size_t pos) : _buffer(buf), _pos(pos)
 
  328        inline reference operator*()
 const 
  330            return _buffer->_buf[_pos % _buffer->capacity()];
 
  332        inline pointer operator->()
 const 
  334            return &(_buffer->_buf[_pos % _buffer->capacity()]);
 
  336        inline iterator& operator++()
 
  341        inline iterator& operator--()
 
  346        inline iterator operator++(
int)
 
  348            iterator tmp = *
this;
 
  352        inline iterator operator--(
int)
 
  354            iterator tmp = *
this;
 
  359        friend inline bool operator==(
const iterator& a, 
const iterator& b)
 
  361            return a._buffer == b._buffer && a._pos == b._pos;
 
  363        friend inline bool operator!=(
const iterator& a, 
const iterator& b)
 
  369        CircularBuffer* _buffer;
 
  373    class const_iterator {
 
  375        using iterator_category = std::bidirectional_iterator_tag;
 
  376        using difference_type   = std::ptrdiff_t;
 
  377        using value_type        = CircularBuffer::value_type;
 
  378        using pointer           = 
const CircularBuffer::value_type*;
 
  379        using reference         = CircularBuffer::const_reference;
 
  381        const_iterator() : _buffer(nullptr), _pos(0)
 
  384        const_iterator(
const CircularBuffer* buf, 
size_t pos) : _buffer(buf), _pos(pos)
 
  388        inline reference operator*()
 const 
  390            return _buffer->_buf[_pos % _buffer->capacity()];
 
  392        inline pointer operator->()
 const 
  394            return &(_buffer->_buf[_pos % _buffer->capacity()]);
 
  396        inline const_iterator& operator++()
 
  401        inline const_iterator& operator--()
 
  406        inline const_iterator operator++(
int)
 
  408            const_iterator tmp = *
this;
 
  412        inline const_iterator operator--(
int)
 
  414            const_iterator tmp = *
this;
 
  419        friend inline bool operator==(
const const_iterator& a, 
const const_iterator& b)
 
  421            return a._buffer == b._buffer && a._pos == b._pos;
 
  423        friend inline bool operator!=(
const const_iterator& a, 
const const_iterator& b)
 
  429        const CircularBuffer* _buffer;
 
  437    inline iterator begin() noexcept
 
  439        return iterator(
this, _tail);
 
  441    inline iterator end() noexcept
 
  443        return iterator(
this, _tail + 
size());
 
  445    inline const_iterator cbegin() const noexcept
 
  447        return const_iterator(
this, _tail);
 
  449    inline const_iterator cend() const noexcept
 
  451        return const_iterator(
this, _tail + 
size());
 
  453    inline reverse_iterator rbegin() noexcept
 
  455        return std::reverse_iterator<iterator>(end());
 
  457    inline reverse_iterator rend() noexcept
 
  459        return std::reverse_iterator<iterator>(begin());
 
  461    inline const_reverse_iterator crbegin() const noexcept
 
  463        return std::reverse_iterator<const_iterator>(cend());
 
  465    inline const_reverse_iterator crend() const noexcept
 
  467        return std::reverse_iterator<const_iterator>(cbegin());
 
  472    std::vector<T> _buf{};
 
  473    size_t _cap{}, _head{}, _tail{};
 
 
  483template <
typename T, 
size_t N>
 
  486    using value_type      = T;
 
  487    using size_type       = size_t;
 
  488    using reference       = T&;
 
  489    using const_reference = 
const T&;
 
  490#if __cplusplus >= 201703L 
  503    template <
class InputIter>
 
 
Type CircularBuffer giving size in constructor.
Definition circular_buffer.hpp:32
 
void clear()
Clears the contents.
Definition circular_buffer.hpp:241
 
void push_front(const value_type &v)
Adds an element to the top.
Definition circular_buffer.hpp:247
 
void assign(std::initializer_list< T > il)
assigns values to the container
Definition circular_buffer.hpp:117
 
bool empty() const
checks whether the container is empty
Definition circular_buffer.hpp:209
 
void assign(size_type n, const_reference v)
assigns values to the container
Definition circular_buffer.hpp:105
 
void swap(CircularBuffer &o)
Swaps the contents.
Definition circular_buffer.hpp:300
 
void push_back(const value_type &v)
Adds an element to the end.
Definition circular_buffer.hpp:257
 
return_type front() const
Access the first element.
Definition circular_buffer.hpp:129
 
return_type at(size_type i) const
Access specified element with bounds checking.
Definition circular_buffer.hpp:163
 
return_type back() const
Access the last element.
Definition circular_buffer.hpp:141
 
const_reference operator[](size_type i) const &
Access specified element.
Definition circular_buffer.hpp:153
 
CircularBuffer & operator=(CircularBuffer &&)=default
Move.
 
CircularBuffer & operator=(const CircularBuffer &)=default
Copy.
 
void swap(m5::container::CircularBuffer< T > &a, m5::container::CircularBuffer< T > &b)
Specializes the std::swap algorithm.
Definition circular_buffer.hpp:529
 
void fill(const value_type &v)
Assigns the value to all elements in the container.
Definition circular_buffer.hpp:290
 
void pop_front()
removes the top element
Definition circular_buffer.hpp:267
 
void pop_back()
removes the end element
Definition circular_buffer.hpp:275
 
bool full() const
checks whether the container is full
Definition circular_buffer.hpp:217
 
void assign(InputIterator first, InputIterator last)
Replaces the contents with copies of those in the range [first, last)
Definition circular_buffer.hpp:87
 
size_type size() const
returns the number of elements
Definition circular_buffer.hpp:224
 
size_t read(value_type *outbuf, const size_t num)
Read from buffer.
Definition circular_buffer.hpp:177
 
size_type capacity() const
Returns the number of elements that can be held in currently storage.
Definition circular_buffer.hpp:232
 
Type CircularBuffer giving size in template parameter.
Definition circular_buffer.hpp:484
 
Definition optional.hpp:679
 
Top level namespace of M5.
Definition bit_segment.hpp:17