Pothos  0.7.0-gf7fbae99
The Pothos dataflow programming software suite
OrderedQueue.hpp
Go to the documentation of this file.
1 
12 #pragma once
13 #include <Pothos/Config.hpp>
15 #include <cstdlib> //size_t
16 #include <utility> //std::forward
17 #include <vector>
18 #include <cassert>
19 
20 namespace Pothos {
21 namespace Util {
22 
27 template <typename T>
29 {
30 public:
32  OrderedQueue(void);
33 
35  OrderedQueue(const size_t capacity);
36 
42  bool empty(void) const;
43 
49  template <typename U>
50  void push(U &&elem, const size_t index);
51 
55  const T &front(void) const;
56 
60  T &front(void);
61 
65  void pop(void);
66 
68  size_t capacity(void) const;
69 
70 private:
71  size_t _indexToAck;
72  std::vector<std::pair<T, bool>> _pushedElems;
73  Pothos::Util::RingDeque<T> _readyElems;
74  inline void _wrapIndex(void)
75  {
76  if (++_indexToAck == _pushedElems.size()) _indexToAck = 0;
77  }
78 };
79 
80 template <typename T>
82  _indexToAck(0)
83 {
84  return;
85 }
86 
87 template <typename T>
89  _indexToAck(0),
90  _pushedElems(capacity, std::make_pair(T(), false)),
91  _readyElems(capacity)
92 {
93  return;
94 }
95 
96 template <typename T>
97 bool OrderedQueue<T>::empty(void) const
98 {
99  return _readyElems.empty();
100 }
101 
102 template <typename T>
103 template <typename U>
104 void OrderedQueue<T>::push(U &&elem, const size_t index)
105 {
106  //element was pushed in order, go directly to the queue
107  if (index == _indexToAck)
108  {
109  assert(not _readyElems.full());
110  _readyElems.push_back(std::forward<U>(elem));
111 
112  //increment for the next pushed element
113  _wrapIndex();
114  }
115 
116  //store the element into its position
117  else
118  {
119  assert(index < _pushedElems.size());
120  _pushedElems[index].first = std::forward<U>(elem);
121  _pushedElems[index].second = true;
122  }
123 
124  //look for pushed elements -- but in order
125  while (_pushedElems[_indexToAck].second)
126  {
127  //move the element into the queue
128  assert(not _readyElems.full());
129  _readyElems.push_back(std::move(_pushedElems[_indexToAck].first));
130  _pushedElems[_indexToAck].second = false;
131 
132  //increment for the next pushed element
133  _wrapIndex();
134  }
135 }
136 
137 template <typename T>
138 const T &OrderedQueue<T>::front(void) const
139 {
140  return _readyElems.front();
141 }
142 
143 template <typename T>
145 {
146  return _readyElems.front();
147 }
148 
149 template <typename T>
151 {
152  _readyElems.pop_front();
153 }
154 
155 template <typename T>
156 size_t OrderedQueue<T>::capacity(void) const
157 {
158  return _readyElems.capacity();
159 }
160 
161 } //namespace Util
162 } //namespace Pothos
bool full(void) const
Is the deque full? – num elements == capacity.
Definition: RingDeque.hpp:311
void pop_front(void)
Pop and element from the front of the queue.
Definition: RingDeque.hpp:244
const T & front(void) const
Get a const reference to the front element.
Definition: RingDeque.hpp:253
Definition: ArchiveEntry.hpp:20
void push(U &&elem, const size_t index)
Definition: OrderedQueue.hpp:104
bool empty(void) const
Definition: OrderedQueue.hpp:97
bool empty(void) const
Is the deque empty? – no elements.
Definition: RingDeque.hpp:305
void pop(void)
Definition: OrderedQueue.hpp:150
size_t capacity(void) const
How many elements can be stored?
Definition: RingDeque.hpp:323
void push_back(U &&elem)
Push an element onto the back of the queue.
Definition: RingDeque.hpp:268
size_t capacity(void) const
How many elements can be stored?
Definition: OrderedQueue.hpp:156
const T & front(void) const
Definition: OrderedQueue.hpp:138
Definition: OrderedQueue.hpp:28
OrderedQueue(void)
Construct a size-zero ordered queue.
Definition: OrderedQueue.hpp:81