tRingBuffer.h
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of FZIs ic_workspace.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00012 //
00013 // -- END LICENSE BLOCK ------------------------------------------------
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     // Adjust capacity.
00204     m_buffer.resize(capacity+1);
00205     // Skip elements that will not fit.
00206     old_read += old_size-new_size;
00207     if (old_read >= old_buffer.size())
00208     {
00209       old_read -= old_buffer.size();
00210     }
00211     // Copy the rest.
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     // Update pointers.
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


fzi_icl_core
Author(s):
autogenerated on Thu Jun 6 2019 20:22:24