gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
circular_queue.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2018 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #ifndef __BASE_CIRCULAR_QUEUE_HH__
39 #define __BASE_CIRCULAR_QUEUE_HH__
40 
41 #include <cassert>
42 #include <cstddef>
43 #include <cstdint>
44 #include <iterator>
45 #include <type_traits>
46 #include <vector>
47 
65 template <typename T>
67 {
68  protected:
70 
73  const size_t _capacity;
74  size_t _size = 0;
75  size_t _head = 1;
76 
81  public:
82  struct iterator
83  {
84  public:
85  CircularQueue* _cq = nullptr;
86  size_t _idx = 0;
87 
91  iterator(CircularQueue* cq, size_t idx) : _cq(cq), _idx(idx) {}
92  iterator() = default;
93 
100  using value_type = T;
101  using difference_type = std::ptrdiff_t;
103  using const_reference = const value_type&;
104  using pointer = value_type*;
105  using const_pointer = const value_type*;
106  using iterator_category = std::random_access_iterator_tag; // end of api_base_utils
108 
112  static_assert(std::is_same<reference, T&>::value,
113  "reference type is not assignable as required");
114 
118  iterator(const iterator& it) : _cq(it._cq), _idx(it._idx) {}
119 
123  iterator&
124  operator=(const iterator& it)
125  {
126  _cq = it._cq;
127  _idx = it._idx;
128  return *this;
129  }
130 
139  bool
141  {
142  return _cq != nullptr && _cq->isValidIdx(_idx);
143  }
144 
154  bool
155  operator==(const iterator& that) const
156  {
157  return _cq == that._cq && _idx == that._idx;
158  }
159 
167  bool operator!=(const iterator& that) { return !(*this == that); }
168 
174  reference
176  {
177  // This has to be dereferenceable.
178  return (*_cq)[_idx];
179  }
180 
185  operator*() const
186  {
187  // This has to be dereferenceable.
188  return (*_cq)[_idx];
189  }
190 
197  pointer operator->() { return &**this; }
198 
202  const_pointer operator->() const { return &**this; }
203 
209  iterator&
211  {
212  ++_idx;
213  return *this;
214  }
215 
221  iterator
223  {
224  iterator t = *this;
225  ++*this;
226  return t;
227  }
228 
234  public:
240  iterator&
242  {
243  /* this has to be decrementable. */
244  assert(_cq && _idx > _cq->head());
245  --_idx;
246  return *this;
247  }
248 
254  iterator
256  {
257  iterator t = *this;
258  --*this;
259  return t;
260  }
261 
267  iterator&
269  {
270  _idx += t;
271  return *this;
272  }
273 
277  iterator&
279  {
280  assert(_cq && _idx >= _cq->head() + t);
281  _idx -= t;
282  return *this;
283  }
284 
290  iterator
292  {
293  iterator ret(*this);
294  return ret += t;
295  }
296 
300  friend iterator
302  {
303  iterator ret = it;
304  return ret += t;
305  }
306 
312  iterator
314  {
315  iterator ret(*this);
316  return ret -= t;
317  }
318 
322  friend iterator
324  {
325  iterator ret = it;
326  return ret -= t;
327  }
328 
336  operator-(const iterator& that)
337  {
338  return (ssize_t)_idx - (ssize_t)that._idx;
339  }
340 
347  template<typename Idx>
348  typename std::enable_if_t<std::is_integral<Idx>::value, reference>
349  operator[](const Idx& index)
350  {
351  return *(*this + index);
352  }
353 
359  bool
360  operator<(const iterator& that) const
361  {
362  return _idx < that._idx;
363  }
364 
368  bool operator>(const iterator& that) const { return !(*this <= that); }
369 
373  bool operator>=(const iterator& that) const { return !(*this < that); }
374 
378  bool operator<=(const iterator& that) const { return !(that < *this); }
379 
383  size_t idx() const { return _idx; }
384  };
385 
386  public:
390  template <typename Idx>
391  typename std::enable_if_t<std::is_integral<Idx>::value, reference>
392  operator[](const Idx& index)
393  {
394  assert(index >= 0);
395  return data[index % _capacity];
396  }
397 
398  template <typename Idx>
399  typename std::enable_if_t<std::is_integral<Idx>::value, const_reference>
400  operator[](const Idx& index) const
401  {
402  assert(index >= 0);
403  return data[index % _capacity];
404  }
405 
409  explicit CircularQueue(size_t size=0) : data(size), _capacity(size) {}
410 
419  void
421  {
422  _head = 1;
423  _size = 0;
424  }
425 
429  bool
430  isValidIdx(size_t idx) const
431  {
432  return _head <= idx && idx < (_head + _size);
433  }
434 
438  reference front() { return (*this)[head()]; }
439 
443  reference back() { return (*this)[tail()]; }
444 
448  size_t head() const { return _head; }
449 
453  size_t tail() const { return _head + _size - 1; }
454 
458  size_t capacity() const { return _capacity; }
459 
463  size_t size() const { return _size; }
464 
473  void
474  pop_front(size_t num_elem=1)
475  {
476  assert(num_elem <= size());
477  _head += num_elem;
478  _size -= num_elem;
479  }
480 
486  void
488  {
489  assert(!empty());
490  --_size;
491  }
492 
498  void
500  {
501  advance_tail();
502  back() = val;
503  }
504 
511  void
513  {
514  if (full())
515  ++_head;
516  else
517  ++_size;
518  }
519 
528  void
530  {
531  size_t remaining = _capacity - _size;
532  if (len > remaining) {
533  size_t overflow = len - remaining;
534  _head += overflow;
535  len -= overflow;
536  }
537  _size += len;
538  }
539 
545  bool empty() const { return _size == 0; }
546 
555  bool full() const { return _size == _capacity; }
556 
562  iterator begin() { return iterator(this, _head); }
563 
564  /* TODO: This should return a const_iterator. */
568  iterator
569  begin() const
570  {
571  return iterator(const_cast<CircularQueue*>(this), _head);
572  }
573 
577  iterator end() { return iterator(this, tail() + 1); }
578 
582  iterator
583  end() const
584  {
585  return iterator(const_cast<CircularQueue*>(this), tail() + 1);
586  }
587 
589  iterator getIterator(size_t idx) { return iterator(this, idx); }
590 };
591 
592 #endif /* __BASE_CIRCULARQUEUE_HH__ */
CircularQueue::iterator::operator->
pointer operator->()
Dereference operator.
Definition: circular_queue.hh:197
CircularQueue::iterator::_idx
size_t _idx
Definition: circular_queue.hh:86
CircularQueue::iterator::difference_type
std::ptrdiff_t difference_type
Definition: circular_queue.hh:101
CircularQueue::iterator::const_reference
const value_type & const_reference
Definition: circular_queue.hh:103
CircularQueue::size
size_t size() const
Definition: circular_queue.hh:463
CircularQueue::advance_tail
void advance_tail()
Increases the tail by one.
Definition: circular_queue.hh:512
CircularQueue::iterator::dereferenceable
bool dereferenceable() const
Test dereferenceability.
Definition: circular_queue.hh:140
MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:44
CircularQueue::iterator::operator+
iterator operator+(const difference_type &t)
Addition operator.
Definition: circular_queue.hh:291
CircularQueue::iterator::operator-
difference_type operator-(const iterator &that)
Difference operator.
Definition: circular_queue.hh:336
CircularQueue::iterator::operator+
friend iterator operator+(const difference_type &t, iterator &it)
Definition: circular_queue.hh:301
CircularQueue::getIterator
iterator getIterator(size_t idx)
Return an iterator to an index in the queue.
Definition: circular_queue.hh:589
CircularQueue::head
size_t head() const
Definition: circular_queue.hh:448
CircularQueue::iterator::operator++
iterator operator++(int)
Post-increment operator.
Definition: circular_queue.hh:222
CircularQueue::iterator::operator--
iterator & operator--()
ForwardIterator The multipass guarantee is provided by the reliance on _idx.
Definition: circular_queue.hh:241
CircularQueue::iterator::operator*
const_reference operator*() const
Definition: circular_queue.hh:185
CircularQueue::iterator::operator[]
std::enable_if_t< std::is_integral< Idx >::value, reference > operator[](const Idx &index)
Index operator.
Definition: circular_queue.hh:349
CircularQueue::iterator::value_type
T value_type
Iterator Traits.
Definition: circular_queue.hh:100
sc_dt::overflow
static void overflow(double &c, const scfx_params &params, bool &o_flag)
Definition: sc_fxnum.cc:459
CircularQueue::pop_back
void pop_back()
Circularly decrease the tail pointer.
Definition: circular_queue.hh:487
CircularQueue
Circular queue.
Definition: circular_queue.hh:66
CircularQueue::iterator::operator-
iterator operator-(const difference_type &t)
Substraction operator.
Definition: circular_queue.hh:313
CircularQueue::begin
iterator begin()
Iterators.
Definition: circular_queue.hh:562
std::vector
STL vector class.
Definition: stl.hh:37
CircularQueue::iterator::iterator
iterator()=default
CircularQueue::flush
void flush()
Remove all the elements in the queue.
Definition: circular_queue.hh:420
CircularQueue::iterator
Iterator to the circular queue.
Definition: circular_queue.hh:82
CircularQueue::iterator::operator++
iterator & operator++()
Pre-increment operator.
Definition: circular_queue.hh:210
CircularQueue::full
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...
Definition: circular_queue.hh:555
CircularQueue::advance_tail
void advance_tail(size_t len)
Increases the tail by a specified number of steps.
Definition: circular_queue.hh:529
CircularQueue::tail
size_t tail() const
Definition: circular_queue.hh:453
CircularQueue::back
reference back()
Definition: circular_queue.hh:443
CircularQueue::iterator::operator>
bool operator>(const iterator &that) const
Definition: circular_queue.hh:368
CircularQueue::data
std::vector< T > data
Definition: circular_queue.hh:69
CircularQueue::iterator::operator+=
iterator & operator+=(const difference_type &t)
RandomAccessIterator requirements.
Definition: circular_queue.hh:268
CircularQueue::iterator::const_pointer
const value_type * const_pointer
Definition: circular_queue.hh:105
CircularQueue::front
reference front()
Definition: circular_queue.hh:438
CircularQueue::iterator::iterator
iterator(CircularQueue *cq, size_t idx)
Definition: circular_queue.hh:91
CircularQueue::iterator::operator--
iterator operator--(int)
Post-decrement operator.
Definition: circular_queue.hh:255
CircularQueue::iterator::iterator
iterator(const iterator &it)
Trait reference type iterator satisfies OutputIterator, therefore reference must be T&.
Definition: circular_queue.hh:118
CircularQueue::iterator::idx
size_t idx() const
OutputIterator has no extra requirements.
Definition: circular_queue.hh:383
CircularQueue::push_back
void push_back(typename std::vector< T >::value_type val)
Pushes an element at the end of the queue.
Definition: circular_queue.hh:499
CircularQueue::end
iterator end()
Definition: circular_queue.hh:577
CircularQueue::operator[]
std::enable_if_t< std::is_integral< Idx >::value, reference > operator[](const Idx &index)
Definition: circular_queue.hh:392
CircularQueue::iterator::reference
value_type & reference
Definition: circular_queue.hh:102
CircularQueue::iterator::operator-=
iterator & operator-=(const difference_type &t)
Definition: circular_queue.hh:278
CircularQueue::end
iterator end() const
Definition: circular_queue.hh:583
X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
CircularQueue::iterator::operator>=
bool operator>=(const iterator &that) const
Definition: circular_queue.hh:373
CircularQueue::iterator::_cq
CircularQueue * _cq
Definition: circular_queue.hh:85
CircularQueue::pop_front
void pop_front(size_t num_elem=1)
Circularly increase the head pointer.
Definition: circular_queue.hh:474
CircularQueue::iterator::operator<=
bool operator<=(const iterator &that) const
Definition: circular_queue.hh:378
CircularQueue::iterator::operator<
bool operator<(const iterator &that) const
Comparisons.
Definition: circular_queue.hh:360
CircularQueue::_size
size_t _size
Definition: circular_queue.hh:74
CircularQueue::iterator::operator*
reference operator*()
Dereference operator.
Definition: circular_queue.hh:175
CircularQueue::empty
bool empty() const
Is the queue empty?
Definition: circular_queue.hh:545
CircularQueue::iterator::operator-
friend iterator operator-(const difference_type &t, iterator &it)
Definition: circular_queue.hh:323
CircularQueue::iterator::iterator_category
std::random_access_iterator_tag iterator_category
Definition: circular_queue.hh:106
CircularQueue::iterator::operator==
bool operator==(const iterator &that) const
InputIterator.
Definition: circular_queue.hh:155
CircularQueue::capacity
size_t capacity() const
Definition: circular_queue.hh:458
ArmISA::t
Bitfield< 5 > t
Definition: miscregs_types.hh:67
CircularQueue::_head
size_t _head
Definition: circular_queue.hh:75
ArmISA::len
Bitfield< 18, 16 > len
Definition: miscregs_types.hh:439
CircularQueue::iterator::operator!=
bool operator!=(const iterator &that)
Inequality operator.
Definition: circular_queue.hh:167
CircularQueue< Prefetcher::STeMS::RegionMissOrderBufferEntry >::reference
typename std::vector< Prefetcher::STeMS::RegionMissOrderBufferEntry >::reference reference
Definition: circular_queue.hh:71
CircularQueue::iterator::operator->
const_pointer operator->() const
Definition: circular_queue.hh:202
CircularQueue::begin
iterator begin() const
Definition: circular_queue.hh:569
CircularQueue::iterator::operator=
iterator & operator=(const iterator &it)
Definition: circular_queue.hh:124
CircularQueue::_capacity
const size_t _capacity
Definition: circular_queue.hh:73
CircularQueue::isValidIdx
bool isValidIdx(size_t idx) const
Test if the index is in the range of valid elements.
Definition: circular_queue.hh:430
CircularQueue< Prefetcher::STeMS::RegionMissOrderBufferEntry >::const_reference
typename std::vector< Prefetcher::STeMS::RegionMissOrderBufferEntry >::const_reference const_reference
Definition: circular_queue.hh:72
CircularQueue::iterator::pointer
value_type * pointer
Definition: circular_queue.hh:104
CircularQueue::CircularQueue
CircularQueue(size_t size=0)
Definition: circular_queue.hh:409
CircularQueue::operator[]
std::enable_if_t< std::is_integral< Idx >::value, const_reference > operator[](const Idx &index) const
Definition: circular_queue.hh:400

Generated on Tue Jun 22 2021 15:28:25 for gem5 by doxygen 1.8.17