MRPT  1.9.9
circular_buffer.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #ifndef circular_buffer_H
10 #define circular_buffer_H
11 
12 #include <vector>
13 #include <stdexcept>
14 
15 namespace mrpt::containers
16 {
17 /** A circular buffer of fixed size (defined at construction-time), implemented
18  * with a std::vector as the underlying storage.
19  * \note Defined in #include <mrpt/containers/circular_buffer.h>
20  * \ingroup mrpt_containers_grp
21  */
22 template <typename T>
24 {
25  private:
26  std::vector<T> m_data;
27  /** not "const" to allow copy/move = ops. */
28  size_t m_size;
30 
31  public:
32  circular_buffer(const size_t size)
34  {
35  if (m_size <= 2) throw std::invalid_argument("size must be >2");
36  }
37 
38  /** Insert a copy of the given element in the buffer.
39  * \exception std::out_of_range If the buffer run out of space.
40  */
41  void push(T d)
42  {
43  auto new_idx = m_next_write + 1;
44  if (new_idx == m_size) new_idx = 0;
45  if (new_idx == m_next_read)
46  throw std::out_of_range("push: circular_buffer is full");
47  m_data[m_next_write] = d;
48  m_next_write = new_idx;
49  }
50 
51  /** Insert a reference of the given element in the buffer.
52  * \exception std::out_of_range If the buffer run out of space.
53  */
54  void push_ref(const T& d)
55  {
56  m_data[m_next_write++] = d;
57  if (m_next_write == m_size) m_next_write = 0;
58 
60  throw std::out_of_range("push: circular_buffer is full");
61  }
62 
63  /** Insert an array of elements in the buffer.
64  * \exception std::out_of_range If the buffer run out of space.
65  */
66  void push_many(T* array_elements, size_t count)
67  {
68  while (count--) push(*array_elements++);
69  }
70 
71  /** Retrieve an element from the buffer.
72  * \exception std::out_of_range If the buffer is empty.
73  */
74  T pop()
75  {
77  throw std::out_of_range("pop: circular_buffer is empty");
78 
79  const size_t i = m_next_read++;
80  if (m_next_read == m_size) m_next_read = 0;
81  return m_data[i];
82  }
83 
84  /** Retrieve an element from the buffer.
85  * \exception std::out_of_range If the buffer is empty.
86  */
87  void pop(T& out_val)
88  {
90  throw std::out_of_range("pop: circular_buffer is empty");
91 
92  out_val = m_data[m_next_read++];
93  if (m_next_read == m_size) m_next_read = 0;
94  }
95 
96  /** Pop a number of elements into a user-provided array.
97  * \exception std::out_of_range If the buffer has less elements than
98  * requested. */
99  void pop_many(T* out_array, size_t count)
100  {
101  while (count--) pop(*out_array++);
102  }
103 
104  /** Peek (see without modifying) what is to be read from the buffer if pop()
105  * was to be called.
106  * \exception std::out_of_range If the buffer is empty. */
107  T peek() const
108  {
109  if (m_next_read == m_next_write)
110  throw std::out_of_range("peek: circular_buffer is empty");
111  return m_data[m_next_read];
112  }
113  /** Like peek(), but seeking ahead in the buffer (index=0 means the
114  * immediate next element, index=1 the following one, etc.)
115  * \exception std::out_of_range If trying to read passing the number of
116  * available elements. */
117  T peek(size_t index) const
118  {
119  if (index >= this->size())
120  throw std::out_of_range("peek: seek out of range");
121  return m_data[(m_next_read + index) % m_size];
122  }
123 
124  /** Like peek(), for multiple elements, storing a number of elements into a
125  * user-provided array.
126  * \exception std::out_of_range If the buffer has less elements than
127  * requested. */
128  void peek_many(T* out_array, size_t count) const
129  {
130  size_t peek_read = m_next_read;
131  while (count--)
132  {
133  if (peek_read == m_next_write)
134  throw std::out_of_range("peek: circular_buffer is empty");
135  T val = m_data[peek_read++];
136  if (peek_read == m_size) peek_read = 0;
137  *out_array++ = val;
138  }
139  }
140 
141  /** Return the number of elements available for read ("pop") in the buffer
142  * (this is NOT the maximum size of the internal buffer)
143  * \sa capacity */
144  size_t size() const
145  {
146  if (m_next_write >= m_next_read)
147  return m_next_write - m_next_read;
148  else
149  return m_next_write + (m_size - m_next_read);
150  }
151 
152  /** Return the maximum capacity of the buffer.
153  * \sa size
154  */
155  size_t capacity() const { return m_size; }
156  /** The maximum number of elements that can be written ("push") without
157  * rising an overflow error.
158  */
159  size_t available() const { return (capacity() - size()) - 1; }
160  /** Delete all the stored data, if any. */
161  void clear() { m_next_write = m_next_read = 0; }
162 }; // end class circular_buffer
163 
164 }
165 #endif
166 
167 
size_t available() const
The maximum number of elements that can be written ("push") without rising an overflow error...
GLuint GLuint GLsizei count
Definition: glext.h:3528
size_t capacity() const
Return the maximum capacity of the buffer.
void push_ref(const T &d)
Insert a reference of the given element in the buffer.
T pop()
Retrieve an element from the buffer.
T peek() const
Peek (see without modifying) what is to be read from the buffer if pop() was to be called...
GLuint index
Definition: glext.h:4054
int val
Definition: mrpt_jpeglib.h:955
size_t size() const
Return the number of elements available for read ("pop") in the buffer (this is NOT the maximum size ...
void pop(T &out_val)
Retrieve an element from the buffer.
void pop_many(T *out_array, size_t count)
Pop a number of elements into a user-provided array.
void peek_many(T *out_array, size_t count) const
Like peek(), for multiple elements, storing a number of elements into a user-provided array...
A circular buffer of fixed size (defined at construction-time), implemented with a std::vector as the...
size_t m_size
not "const" to allow copy/move = ops.
T peek(size_t index) const
Like peek(), but seeking ahead in the buffer (index=0 means the immediate next element, index=1 the following one, etc.)
void push_many(T *array_elements, size_t count)
Insert an array of elements in the buffer.
GLsizeiptr size
Definition: glext.h:3923
void push(T d)
Insert a copy of the given element in the buffer.
void clear()
Delete all the stored data, if any.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020