Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00028
00029 #ifndef ICL_CORE_T_RING_BUFFER_H_INCLUDED
00030 #define ICL_CORE_T_RING_BUFFER_H_INCLUDED
00031
00032 #include <stdexcept>
00033 #include <vector>
00034
00035 #include "icl_core/BaseTypes.h"
00036 #include "icl_core/Deprecate.h"
00037
00038 namespace icl_core {
00039
00042 template <typename T>
00043 class ICL_CORE_VC_DEPRECATE tRingBuffer
00044 {
00045 public:
00046 typedef T value_type;
00047 typedef size_t size_type;
00048 static const size_type cDEFAULT_CAPACITY = 32;
00049
00051 tRingBuffer(size_type capacity = cDEFAULT_CAPACITY)
00052 : m_buffer(capacity+1), m_write(0), m_read(0)
00053 { }
00054
00056 tRingBuffer(const tRingBuffer<T>& other)
00057 : m_buffer(other.m_buffer), m_write(other.m_write), m_read(other.m_read)
00058 { }
00059
00061 tRingBuffer& operator = (const tRingBuffer<T>& other)
00062 {
00063 m_buffer = other.m_buffer;
00064 m_write = other.m_write;
00065 m_read = other.m_read;
00066 return *this;
00067 }
00068
00070 void Clear() { m_write = m_read = 0; }
00071
00073
00077 void Write(const T& val, bool overwrite=false)
00078 {
00079 size_type new_write_pos = m_write+1;
00080 if (new_write_pos >= m_buffer.size())
00081 {
00082 new_write_pos = 0;
00083 }
00084 if (new_write_pos == m_read)
00085 {
00086 if (overwrite)
00087 {
00088 Skip();
00089 }
00090 else
00091 {
00092 throw std::out_of_range("tRingBuffer::Write: capacity exceeded");
00093 }
00094 }
00095 m_buffer[m_write] = val;
00096 m_write = new_write_pos;
00097 }
00098
00100
00104 const T& At(size_type pos) const
00105 {
00106 if (pos < Size())
00107 {
00108 pos += m_read;
00109 if (pos >= m_buffer.size())
00110 {
00111 pos -= m_buffer.size();
00112 }
00113 return m_buffer[pos];
00114 }
00115 else
00116 {
00117 throw std::out_of_range("tRingBuffer::Peek: out of range");
00118 }
00119 }
00120
00122
00126 T& At(size_type pos)
00127 {
00128 if (pos < Size())
00129 {
00130 pos += m_read;
00131 if (pos >= m_buffer.size())
00132 {
00133 pos -= m_buffer.size();
00134 }
00135 return m_buffer[pos];
00136 }
00137 else
00138 {
00139 throw std::out_of_range("tRingBuffer::Peek: out of range");
00140 }
00141 }
00142
00144 void Skip()
00145 {
00146 if (m_write == m_read)
00147 {
00148 throw std::out_of_range("tRingBuffer::Skip: buffer empty");
00149 }
00150 m_read++;
00151 if (m_read >= m_buffer.size())
00152 {
00153 m_read = 0;
00154 }
00155 }
00156
00158
00160 T Read()
00161 {
00162 if (m_write == m_read)
00163 {
00164 throw std::out_of_range("tRingBuffer::Read: buffer empty");
00165 }
00166 size_type read_pos = m_read;
00167 m_read++;
00168 if (m_read >= m_buffer.size())
00169 {
00170 m_read = 0;
00171 }
00172 return m_buffer[read_pos];
00173 }
00174
00176 inline size_type Size() const
00177 {
00178 if (m_write >= m_read)
00179 {
00180 return m_write-m_read;
00181 }
00182 else
00183 {
00184 return m_write+m_buffer.size()-m_read;
00185 }
00186 }
00187
00189 size_type Capacity() const { return m_buffer.size()-1; }
00190
00192
00196 void SetCapacity(size_type capacity)
00197 {
00198 size_type old_size = Size();
00199 size_type new_size = (capacity < old_size) ? capacity : old_size;
00200 std::vector<T> old_buffer(m_buffer);
00201 size_type old_read = m_read;
00202
00203
00204 m_buffer.resize(capacity+1);
00205
00206 old_read += old_size-new_size;
00207 if (old_read >= old_buffer.size())
00208 {
00209 old_read -= old_buffer.size();
00210 }
00211
00212 for (size_type i=0; i<new_size; i++)
00213 {
00214 m_buffer[i] = old_buffer[old_read];
00215 old_read++;
00216 if (old_read >= old_buffer.size())
00217 {
00218 old_read = 0;
00219 }
00220 }
00221
00222 m_read = 0;
00223 m_write = new_size;
00224 }
00225
00229 ~tRingBuffer()
00230 { }
00231
00232 private:
00233 std::vector<T> m_buffer;
00234 size_type m_write;
00235 size_type m_read;
00236 } ICL_CORE_GCC_DEPRECATE;
00237
00238 }
00239
00240 #endif