gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
48namespace gem5
49{
50
68template <typename T>
70{
71 protected:
73
76 const size_t _capacity;
77 size_t _size = 0;
78 size_t _head = 1;
79
84 public:
85 struct iterator
86 {
87 public:
88 CircularQueue* _cq = nullptr;
89 size_t _idx = 0;
90
94 iterator(CircularQueue* cq, size_t idx) : _cq(cq), _idx(idx) {}
95 iterator() = default;
96
103 using value_type = T;
104 using difference_type = std::ptrdiff_t;
108 using const_pointer = const value_type*;
109 using iterator_category = std::random_access_iterator_tag;
110 // end of api_base_utils
111
115 static_assert(std::is_same_v<reference, T&>,
116 "reference type is not assignable as required");
117
121 iterator(const iterator& it) : _cq(it._cq), _idx(it._idx) {}
122
126 iterator&
128 {
129 _cq = it._cq;
130 _idx = it._idx;
131 return *this;
132 }
133
142 bool
144 {
145 return _cq != nullptr && _cq->isValidIdx(_idx);
146 }
147
157 bool
158 operator==(const iterator& that) const
159 {
160 return _cq == that._cq && _idx == that._idx;
161 }
162
170 bool operator!=(const iterator& that) { return !(*this == that); }
171
179 {
180 // This has to be dereferenceable.
181 return (*_cq)[_idx];
182 }
183
188 operator*() const
189 {
190 // This has to be dereferenceable.
191 return (*_cq)[_idx];
192 }
193
200 pointer operator->() { return &**this; }
201
205 const_pointer operator->() const { return &**this; }
206
212 iterator&
214 {
215 ++_idx;
216 return *this;
217 }
218
226 {
227 iterator t = *this;
228 ++*this;
229 return t;
230 }
231
237 public:
243 iterator&
245 {
246 /* this has to be decrementable. */
247 assert(_cq && _idx > _cq->head());
248 --_idx;
249 return *this;
250 }
251
259 {
260 iterator t = *this;
261 --*this;
262 return t;
263 }
264
270 iterator&
272 {
273 _idx += t;
274 return *this;
275 }
276
280 iterator&
282 {
283 assert(_cq && _idx >= _cq->head() + t);
284 _idx -= t;
285 return *this;
286 }
287
295 {
296 iterator ret(*this);
297 return ret += t;
298 }
299
303 friend iterator
305 {
306 iterator ret = it;
307 return ret += t;
308 }
309
317 {
318 iterator ret(*this);
319 return ret -= t;
320 }
321
325 friend iterator
327 {
328 iterator ret = it;
329 return ret -= t;
330 }
331
339 operator-(const iterator& that)
340 {
341 return (ssize_t)_idx - (ssize_t)that._idx;
342 }
343
350 template<typename Idx>
351 typename std::enable_if_t<std::is_integral_v<Idx>, reference>
352 operator[](const Idx& index)
353 {
354 return *(*this + index);
355 }
356
362 bool
363 operator<(const iterator& that) const
364 {
365 return _idx < that._idx;
366 }
367
371 bool operator>(const iterator& that) const { return !(*this <= that); }
372
376 bool operator>=(const iterator& that) const { return !(*this < that); }
377
381 bool operator<=(const iterator& that) const { return !(that < *this); }
382
386 size_t idx() const { return _idx; }
387 };
388
389 public:
393 template <typename Idx>
394 typename std::enable_if_t<std::is_integral_v<Idx>, reference>
395 operator[](const Idx& index)
396 {
397 assert(index >= 0);
398 return data[index % _capacity];
399 }
400
401 template <typename Idx>
402 typename std::enable_if_t<std::is_integral_v<Idx>, const_reference>
403 operator[](const Idx& index) const
404 {
405 assert(index >= 0);
406 return data[index % _capacity];
407 }
408
412 explicit CircularQueue(size_t size=0) : data(size), _capacity(size) {}
413
422 void
424 {
425 _head = 1;
426 _size = 0;
427 }
428
432 bool
433 isValidIdx(size_t idx) const
434 {
435 return _head <= idx && idx < (_head + _size);
436 }
437
441 reference front() { return (*this)[head()]; }
442
446 reference back() { return (*this)[tail()]; }
447
451 size_t head() const { return _head; }
452
456 size_t tail() const { return _head + _size - 1; }
457
461 size_t capacity() const { return _capacity; }
462
466 size_t size() const { return _size; }
467
476 void
477 pop_front(size_t num_elem=1)
478 {
479 assert(num_elem <= size());
480 _head += num_elem;
481 _size -= num_elem;
482 }
483
489 void
491 {
492 assert(!empty());
493 --_size;
494 }
495
501 void
503 {
504 advance_tail();
505 back() = val;
506 }
507
514 void
516 {
517 if (full())
518 ++_head;
519 else
520 ++_size;
521 }
522
531 void
533 {
534 size_t remaining = _capacity - _size;
535 if (len > remaining) {
536 size_t overflow = len - remaining;
537 _head += overflow;
538 len -= overflow;
539 }
540 _size += len;
541 }
542
548 bool empty() const { return _size == 0; }
549
558 bool full() const { return _size == _capacity; }
559
565 iterator begin() { return iterator(this, _head); }
566
567 /* TODO: This should return a const_iterator. */
571 iterator
572 begin() const
573 {
574 return iterator(const_cast<CircularQueue*>(this), _head);
575 }
576
580 iterator end() { return iterator(this, tail() + 1); }
581
585 iterator
586 end() const
587 {
588 return iterator(const_cast<CircularQueue*>(this), tail() + 1);
589 }
590
592 iterator getIterator(size_t idx) { return iterator(this, idx); }
593};
594
595} // namespace gem5
596
597#endif /* __BASE_CIRCULARQUEUE_HH__ */
Circular queue.
bool isValidIdx(size_t idx) const
Test if the index is in the range of valid elements.
std::enable_if_t< std::is_integral_v< Idx >, const_reference > operator[](const Idx &index) const
typename std::vector< T >::reference reference
iterator getIterator(size_t idx)
Return an iterator to an index in the queue.
typename std::vector< T >::const_reference const_reference
std::vector< T > data
STL vector class.
Definition stl.hh:37
CircularQueue(size_t size=0)
std::enable_if_t< std::is_integral_v< Idx >, reference > operator[](const Idx &index)
Index operator.
iterator begin() const
void push_back(typename std::vector< T >::value_type val)
Pushes an element at the end of the queue.
bool operator<(const iterator &that) const
Comparisons.
pointer operator->()
Dereference operator.
difference_type operator-(const iterator &that)
Difference operator.
iterator end() const
void flush()
Remove all the elements in the queue.
const_reference operator*() const
iterator & operator--()
ForwardIterator The multipass guarantee is provided by the reliance on _idx.
bool operator>=(const iterator &that) const
iterator operator-(const difference_type &t)
Substraction operator.
friend iterator operator+(const difference_type &t, iterator &it)
void pop_front(size_t num_elem=1)
Circularly increase the head pointer.
iterator & operator+=(const difference_type &t)
RandomAccessIterator requirements.
bool operator==(const iterator &that) const
InputIterator.
bool dereferenceable() const
Test dereferenceability.
bool empty() const
Is the queue empty?
iterator operator++(int)
Post-increment operator.
friend iterator operator-(const difference_type &t, iterator &it)
const value_type & const_reference
void pop_back()
Circularly decrease the tail pointer.
iterator operator--(int)
Post-decrement operator.
bool operator!=(const iterator &that)
Inequality operator.
std::random_access_iterator_tag iterator_category
void advance_tail()
Increases the tail by one.
iterator & operator=(const iterator &it)
iterator(const iterator &it)
Trait reference type iterator satisfies OutputIterator, therefore reference must be T&.
iterator operator+(const difference_type &t)
Addition operator.
bool operator>(const iterator &that) const
std::enable_if_t< std::is_integral_v< Idx >, reference > operator[](const Idx &index)
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...
iterator begin()
Iterators.
void advance_tail(size_t len)
Increases the tail by a specified number of steps.
bool operator<=(const iterator &that) const
iterator & operator-=(const difference_type &t)
const_pointer operator->() const
reference operator*()
Dereference operator.
iterator & operator++()
Pre-increment operator.
size_t capacity() const
iterator(CircularQueue *cq, size_t idx)
Bitfield< 18, 16 > len
Bitfield< 5 > t
Definition misc_types.hh:71
Bitfield< 30, 0 > index
Bitfield< 63 > val
Definition misc.hh:804
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
Iterator to the circular queue.
size_t idx() const
OutputIterator has no extra requirements.

Generated on Tue Jun 18 2024 16:24:00 for gem5 by doxygen 1.11.0