tRingBuffer.h
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 // This file is part of FZIs ic_workspace.
5 //
6 // This program is free software licensed under the LGPL
7 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
8 // You can find a copy of this license in LICENSE folder in the top
9 // directory of the source code.
10 //
11 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
12 //
13 // -- END LICENSE BLOCK ------------------------------------------------
14 
15 //----------------------------------------------------------------------
28 //----------------------------------------------------------------------
29 #ifndef ICL_CORE_T_RING_BUFFER_H_INCLUDED
30 #define ICL_CORE_T_RING_BUFFER_H_INCLUDED
31 
32 #include <stdexcept>
33 #include <vector>
34 
35 #include "icl_core/BaseTypes.h"
36 #include "icl_core/Deprecate.h"
37 
38 namespace icl_core {
39 
42 template <typename T>
44 {
45 public:
46  typedef T value_type;
47  typedef size_t size_type;
48  static const size_type cDEFAULT_CAPACITY = 32;
49 
51  tRingBuffer(size_type capacity = cDEFAULT_CAPACITY)
52  : m_buffer(capacity+1), m_write(0), m_read(0)
53  { }
54 
57  : m_buffer(other.m_buffer), m_write(other.m_write), m_read(other.m_read)
58  { }
59 
61  tRingBuffer& operator = (const tRingBuffer<T>& other)
62  {
63  m_buffer = other.m_buffer;
64  m_write = other.m_write;
65  m_read = other.m_read;
66  return *this;
67  }
68 
70  void Clear() { m_write = m_read = 0; }
71 
73 
77  void Write(const T& val, bool overwrite=false)
78  {
79  size_type new_write_pos = m_write+1;
80  if (new_write_pos >= m_buffer.size())
81  {
82  new_write_pos = 0;
83  }
84  if (new_write_pos == m_read)
85  {
86  if (overwrite)
87  {
88  Skip();
89  }
90  else
91  {
92  throw std::out_of_range("tRingBuffer::Write: capacity exceeded");
93  }
94  }
95  m_buffer[m_write] = val;
96  m_write = new_write_pos;
97  }
98 
100 
104  const T& At(size_type pos) const
105  {
106  if (pos < Size())
107  {
108  pos += m_read;
109  if (pos >= m_buffer.size())
110  {
111  pos -= m_buffer.size();
112  }
113  return m_buffer[pos];
114  }
115  else
116  {
117  throw std::out_of_range("tRingBuffer::Peek: out of range");
118  }
119  }
120 
122 
126  T& At(size_type pos)
127  {
128  if (pos < Size())
129  {
130  pos += m_read;
131  if (pos >= m_buffer.size())
132  {
133  pos -= m_buffer.size();
134  }
135  return m_buffer[pos];
136  }
137  else
138  {
139  throw std::out_of_range("tRingBuffer::Peek: out of range");
140  }
141  }
142 
144  void Skip()
145  {
146  if (m_write == m_read)
147  {
148  throw std::out_of_range("tRingBuffer::Skip: buffer empty");
149  }
150  m_read++;
151  if (m_read >= m_buffer.size())
152  {
153  m_read = 0;
154  }
155  }
156 
158 
160  T Read()
161  {
162  if (m_write == m_read)
163  {
164  throw std::out_of_range("tRingBuffer::Read: buffer empty");
165  }
166  size_type read_pos = m_read;
167  m_read++;
168  if (m_read >= m_buffer.size())
169  {
170  m_read = 0;
171  }
172  return m_buffer[read_pos];
173  }
174 
176  inline size_type Size() const
177  {
178  if (m_write >= m_read)
179  {
180  return m_write-m_read;
181  }
182  else
183  {
184  return m_write+m_buffer.size()-m_read;
185  }
186  }
187 
189  size_type Capacity() const { return m_buffer.size()-1; }
190 
192 
196  void SetCapacity(size_type capacity)
197  {
198  size_type old_size = Size();
199  size_type new_size = (capacity < old_size) ? capacity : old_size;
200  std::vector<T> old_buffer(m_buffer);
201  size_type old_read = m_read;
202 
203  // Adjust capacity.
204  m_buffer.resize(capacity+1);
205  // Skip elements that will not fit.
206  old_read += old_size-new_size;
207  if (old_read >= old_buffer.size())
208  {
209  old_read -= old_buffer.size();
210  }
211  // Copy the rest.
212  for (size_type i=0; i<new_size; i++)
213  {
214  m_buffer[i] = old_buffer[old_read];
215  old_read++;
216  if (old_read >= old_buffer.size())
217  {
218  old_read = 0;
219  }
220  }
221  // Update pointers.
222  m_read = 0;
223  m_write = new_size;
224  }
225 
230  { }
231 
232 private:
233  std::vector<T> m_buffer;
234  size_type m_write;
235  size_type m_read;
237 
238 }
239 
240 #endif
tRingBuffer(const tRingBuffer< T > &other)
Copy constructor.
Definition: tRingBuffer.h:56
size_type Capacity() const
Returns the capacity of the ring buffer.
Definition: tRingBuffer.h:189
#define ICL_CORE_VC_DEPRECATE
Definition: Deprecate.h:35
void SetCapacity(size_type capacity)
Changes the capacity of the ring buffer.
Definition: tRingBuffer.h:196
A simple ring buffer implementation based on std::vector.
Definition: tRingBuffer.h:43
tRingBuffer(size_type capacity=cDEFAULT_CAPACITY)
Default constructor.
Definition: tRingBuffer.h:51
Contains macros to deprecate classes, types, functions and variables.
T Read()
Removes an element from the ring buffer provided there is one present.
Definition: tRingBuffer.h:160
const T & At(size_type pos) const
Read an arbitrary element from the ring buffer without removing it.
Definition: tRingBuffer.h:104
void Clear()
Clears the ring buffer.
Definition: tRingBuffer.h:70
void Skip()
Removes an element from the ring buffer without returning it.
Definition: tRingBuffer.h:144
size_type Size() const
Returns the current number of elements in the ring buffer.
Definition: tRingBuffer.h:176
Contains Interface base classes and base types.
ICL_CORE_VC_DEPRECATE SetRelation tSetRelation ICL_CORE_GCC_DEPRECATE
Definition: SetHelper.h:42
T & At(size_type pos)
Access an arbitrary element in the ring buffer without removing it.
Definition: tRingBuffer.h:126
void Write(const T &val, bool overwrite=false)
Adds an element to the ring buffer provided there is room.
Definition: tRingBuffer.h:77
std::vector< T > m_buffer
Definition: tRingBuffer.h:233


fzi_icl_core
Author(s):
autogenerated on Mon Jun 10 2019 13:17:58