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-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
16 {
17 namespace containers
18 {
19 /** A circular buffer of fixed size (defined at construction-time), implemented
20  * with a std::vector as the underlying storage.
21  * \note Defined in #include <mrpt/containers/circular_buffer.h>
22  * \ingroup mrpt_containers_grp
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 
40  /** Insert a copy of the given element in the buffer.
41  * \exception std::out_of_range If the buffer run out of space.
42  */
43  void push(T d)
44  {
45  auto new_idx = m_next_write + 1;
46  if (new_idx == m_size) new_idx = 0;
47  if (new_idx == m_next_read)
48  throw std::out_of_range("push: circular_buffer is full");
49  m_data[m_next_write] = d;
50  m_next_write = new_idx;
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
mrpt::containers::circular_buffer::peek_many
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.
Definition: circular_buffer.h:130
mrpt::containers::circular_buffer::m_size
size_t m_size
not "const" to allow copy/move = ops.
Definition: circular_buffer.h:30
mrpt::containers::circular_buffer::clear
void clear()
Delete all the stored data, if any.
Definition: circular_buffer.h:163
mrpt::containers::circular_buffer::peek
T peek(size_t index) const
Like peek(), but seeking ahead in the buffer (index=0 means the immediate next element,...
Definition: circular_buffer.h:119
mrpt::containers::circular_buffer::pop
void pop(T &out_val)
Retrieve an element from the buffer.
Definition: circular_buffer.h:89
mrpt::containers::circular_buffer
A circular buffer of fixed size (defined at construction-time), implemented with a std::vector as the...
Definition: circular_buffer.h:25
mrpt::containers::circular_buffer::pop_many
void pop_many(T *out_array, size_t count)
Pop a number of elements into a user-provided array.
Definition: circular_buffer.h:101
mrpt
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Definition: CKalmanFilterCapable.h:30
val
int val
Definition: mrpt_jpeglib.h:955
mrpt::containers::circular_buffer::circular_buffer
circular_buffer(const size_t size)
Definition: circular_buffer.h:34
mrpt::containers::circular_buffer::capacity
size_t capacity() const
Return the maximum capacity of the buffer.
Definition: circular_buffer.h:157
count
GLuint GLuint GLsizei count
Definition: glext.h:3528
mrpt::containers::circular_buffer::size
size_t size() const
Return the number of elements available for read ("pop") in the buffer (this is NOT the maximum size ...
Definition: circular_buffer.h:146
mrpt::containers::circular_buffer::peek
T peek() const
Peek (see without modifying) what is to be read from the buffer if pop() was to be called.
Definition: circular_buffer.h:109
index
GLuint index
Definition: glext.h:4054
mrpt::containers::circular_buffer::m_data
std::vector< T > m_data
Definition: circular_buffer.h:28
mrpt::containers::circular_buffer::pop
T pop()
Retrieve an element from the buffer.
Definition: circular_buffer.h:76
mrpt::containers::circular_buffer::push_ref
void push_ref(const T &d)
Insert a reference of the given element in the buffer.
Definition: circular_buffer.h:56
mrpt::containers::circular_buffer::m_next_read
size_t m_next_read
Definition: circular_buffer.h:31
mrpt::containers::circular_buffer::push_many
void push_many(T *array_elements, size_t count)
Insert an array of elements in the buffer.
Definition: circular_buffer.h:68
mrpt::containers::circular_buffer::available
size_t available() const
The maximum number of elements that can be written ("push") without rising an overflow error.
Definition: circular_buffer.h:161
mrpt::containers::circular_buffer::m_next_write
size_t m_next_write
Definition: circular_buffer.h:31
mrpt::containers::circular_buffer::push
void push(T d)
Insert a copy of the given element in the buffer.
Definition: circular_buffer.h:43
size
GLsizeiptr size
Definition: glext.h:3923



Page generated by Doxygen 1.8.17 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at miƩ 12 jul 2023 10:03:34 CEST