38 #ifndef __BASE_CIRCULAR_QUEUE_HH__ 39 #define __BASE_CIRCULAR_QUEUE_HH__ 45 #include <type_traits> 86 using typename Base::reference;
87 using typename Base::const_reference;
105 return (op1 + op2) %
size;
112 int32_t ret =
sub(op1, op2, size);
113 return ret >= 0 ? ret : ret +
size;
117 sub(uint32_t op1, uint32_t op2, uint32_t
size)
120 return (op1 - op2) %
size;
122 return -((op2 - op1) % size);
158 : _cq(cq), _idx(idx), _round(round) {}
172 static_assert(std::is_same<reference, T&>::value,
173 "reference type is not assignable as required");
178 : _cq(it._cq), _idx(it._idx), _round(it._round) {}
207 return _cq !=
nullptr && _cq->
isValidIdx(_idx, _round);
220 return _cq == that.
_cq && _idx == that.
_idx &&
230 return !(*
this == that);
251 return &((*_cq)[
_idx]);
256 return &((*_cq)[
_idx]);
294 return _cq && !(_idx == _cq->
head() &&
296 (_idx == 0 && _round != _cq->
_round + 1) ||
297 (_idx !=0 && _round != _cq->
_round)));
372 if (this->_round != that.
_round) {
381 template<
typename Idx>
389 assert(_cq && that.
_cq == _cq);
390 return (this->_round < that.
_round) ||
391 (this->_round == that.
_round && _idx < that.
_idx);
396 {
return !(*
this <= that); }
399 {
return !(*
this < that); }
402 {
return !(that < *
this); }
409 using Base::operator[];
412 : _capacity(
size), _head(1), _tail(0), _empty(true), _round(0)
447 (_head < idx && _tail < idx) ||
448 (_head > idx && _tail >
idx)
449 )) || (_tail < idx && idx < _head));
480 (round == _round && idx <= _tail && (
481 _head <= idx || _head > _tail)) ||
482 (round + 1 == _round &&
499 else if (_head <= _tail)
500 return _tail - _head + 1;
502 return _capacity - _head + _tail + 1;
525 if (num_elem == 0)
return;
528 assert(hIt <=
end());
529 _empty = hIt ==
end();
537 _empty = _head ==
_tail;
559 if (_tail == _head && !_empty)
586 (_tail + 1 == _head || (_tail + 1 == _capacity && _head == 0));
594 else if (_head > _tail)
595 return iterator(
this, _head, _round - 1);
597 return iterator(
this, _head, _round);
605 else if (_head > _tail)
606 return iterator(const_cast<CircularQueue*>(
this), _head,
609 return iterator(const_cast<CircularQueue*>(
this), _head,
628 return iterator(const_cast<CircularQueue*>(
this), poi, round);
645 if (idx >= _head && _head > _tail) {
648 }
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)