40 #ifndef __BASE_CIRCULAR_QUEUE_HH__ 41 #define __BASE_CIRCULAR_QUEUE_HH__ 47 #include <type_traits> 88 using typename Base::reference;
89 using typename Base::const_reference;
107 return (op1 + op2) %
size;
114 int32_t ret =
sub(op1, op2, size);
115 return ret >= 0 ? ret : ret +
size;
119 sub(uint32_t op1, uint32_t op2, uint32_t
size)
122 return (op1 - op2) %
size;
124 return -((op2 - op1) % size);
160 : _cq(cq), _idx(idx), _round(round) {}
174 static_assert(std::is_same<reference, T&>::value,
175 "reference type is not assignable as required");
180 : _cq(it._cq), _idx(it._idx), _round(it._round) {}
209 return _cq !=
nullptr && _cq->
isValidIdx(_idx, _round);
222 return _cq == that.
_cq && _idx == that.
_idx &&
232 return !(*
this == that);
253 return &((*_cq)[
_idx]);
258 return &((*_cq)[
_idx]);
296 return _cq && !(_idx == _cq->
head() &&
298 (_idx == 0 && _round != _cq->
_round + 1) ||
299 (_idx !=0 && _round != _cq->
_round)));
374 if (this->_round != that.
_round) {
383 template<
typename Idx>
391 assert(_cq && that.
_cq == _cq);
392 return (this->_round < that.
_round) ||
393 (this->_round == that.
_round && _idx < that.
_idx);
398 {
return !(*
this <= that); }
401 {
return !(*
this < that); }
404 {
return !(that < *
this); }
411 using Base::operator[];
414 : _capacity(
size), _head(1), _tail(0), _empty(true), _round(0)
449 (_head < idx && _tail < idx) ||
450 (_head > idx && _tail >
idx)
451 )) || (_tail < idx && idx < _head));
482 (round == _round && idx <= _tail && (
483 _head <= idx || _head > _tail)) ||
484 (round + 1 == _round &&
501 else if (_head <= _tail)
502 return _tail - _head + 1;
504 return _capacity - _head + _tail + 1;
527 if (num_elem == 0)
return;
530 assert(hIt <=
end());
531 _empty = hIt ==
end();
539 _empty = _head ==
_tail;
561 if (_tail == _head && !_empty)
588 (_tail + 1 == _head || (_tail + 1 == _capacity && _head == 0));
596 else if (_head > _tail)
597 return iterator(
this, _head, _round - 1);
599 return iterator(
this, _head, _round);
607 else if (_head > _tail)
608 return iterator(const_cast<CircularQueue*>(
this), _head,
611 return iterator(const_cast<CircularQueue*>(
this), _head,
630 return iterator(const_cast<CircularQueue*>(
this), poi, round);
647 if (idx >= _head && _head > _tail) {
650 }
else if (idx < _head && _tail + 1 == _capacity) {
T value_type
Iterator Traits.
Iterator to the circular queue.
iterator begin()
Iterators.
iterator & operator=(const iterator &it)
iterator & operator++()
Pre-increment operator.
static uint32_t moduloAdd(uint32_t op1, uint32_t op2, uint32_t size)
General modular addition.
std::random_access_iterator_tag iterator_category
static int32_t sub(uint32_t op1, uint32_t op2, uint32_t size)
bool full() const
Is the queue full? A queue is full if the head is the 0^{th} element and the tail is the (size-1)^{th...
const value_type * const_pointer
const_pointer operator->() const
uint32_t moduloAdd(uint32_t s1, uint32_t s2) const
bool operator!=(const iterator &that)
Inequality operator.
void decrease(uint32_t &v)
bool operator==(const iterator &that) const
InputIterator.
iterator getIterator(size_t idx)
Return an iterator to an index in the vector.
friend iterator operator+(const difference_type &t, iterator &it)
size_t idx() const
OutputIterator has no extra requirements.
void push_back(typename Base::value_type val)
Pushes an element at the end of the queue.
uint32_t _round
Counter for how many times the tail wraps around.
static uint32_t moduloSub(uint32_t op1, uint32_t op2, uint32_t size)
General modular subtraction.
iterator & operator--()
Pre-decrement operator.
void advance_tail()
Increases the tail by one.
void pop_back()
Circularly decrease the tail pointer.
pointer operator->()
Dereference operator.
iterator & operator-=(const difference_type &t)
uint32_t moduloSub(uint32_t s1, uint32_t s2) const
std::ptrdiff_t difference_type
CircularQueue(uint32_t size=0)
std::enable_if< std::is_integral< Idx >::value, reference >::type operator[](const Idx &index)
Index operator.
const value_type & const_reference
difference_type operator-(const iterator &that)
Difference operator.
bool decrementable() const
ForwardIterator The multipass guarantee is provided by the reliance on _idx.
bool empty() const
Is the queue empty?
void pop_front(size_t num_elem=1)
Circularly increase the head pointer.
iterator operator++(int)
Post-increment operator.
iterator operator+(const difference_type &t)
Addition operator.
bool operator>=(const iterator &that) const
bool isValidIdx(size_t idx, uint32_t round) const
Test if the index is in the range of valid elements.
void flush()
Remove all the elements in the queue.
iterator()
Trait reference type iterator satisfies OutputIterator, therefore reference must be T&...
void increase(uint32_t &v, size_t delta=1)
bool dereferenceable() const
Test dereferenceability.
iterator & operator+=(const difference_type &t)
RandomAccessIterator requirements.
iterator operator--(int)
Post-decrement operator.
bool operator<=(const iterator &that) const
iterator operator-(const difference_type &t)
Substraction operator.
bool operator>(const iterator &that) const
iterator(const iterator &it)
void advance_tail(uint32_t len)
Increases the tail by a specified number of steps.
reference operator*()
Dereference operator.
bool isValidIdx(size_t idx) const
Test if the index is in the range of valid elements.
bool operator<(const iterator &that) const
Comparisons.
friend iterator operator-(const difference_type &t, iterator &it)
const_reference operator*() const
iterator(CircularQueue *cq, uint32_t idx, uint32_t round)