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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019