00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __CIRCULAR_BUFFER_H__
00023 #define __CIRCULAR_BUFFER_H__
00024
00025 #include <iostream>
00026
00027 namespace tlm {
00028
00029 template < typename T >
00030 class circular_buffer
00031 {
00032 public:
00033 circular_buffer( int size );
00034
00035 circular_buffer<T> &operator=( const circular_buffer<T> & );
00036
00037 ~circular_buffer() { delete [] m_buf; }
00038
00039 void resize( int size );
00040
00041 const T &read();
00042 void write( const T & );
00043
00044 bool is_empty() const { return used() == 0; }
00045 bool is_full() const { return free() == 0; }
00046
00047 int size() const { return m_size; }
00048 int used() const { return m_used; }
00049 int free() const { return m_free; }
00050
00051 T &write_data() { return m_buf[m_wi]; }
00052 const T &read_data() const { return m_buf[m_ri]; }
00053
00054 const T &peek_data( int i ) const { return m_buf[(m_ri + i) % size()]; }
00055 T &poke_data( int i ) { return m_buf[(m_ri + i) % size()]; }
00056
00057 void increment_write_pos( int i = 1 );
00058 void increment_read_pos( int i = 1 );
00059
00060 void init();
00061
00062 void debug() const;
00063
00064 private:
00065 circular_buffer( const circular_buffer<T> &b );
00066 void copy( const circular_buffer<T> &b );
00067
00068 private:
00069 int m_size;
00070 T* m_buf;
00071 int m_free;
00072 int m_used;
00073 int m_ri;
00074 int m_wi;
00075
00076 };
00077
00078 template< typename T >
00079 void
00080 circular_buffer<T>::debug() const
00081 {
00082
00083 std::cout << "Buffer debug" << std::endl;
00084 std::cout << "Size : " << size() << std::endl;
00085 std::cout << "Free/Used " << free() << "/" << used() << std::endl;
00086 std::cout << "Indeces : r/w = " << m_ri << "/" << m_wi << std::endl;
00087
00088 if( is_empty() ) {
00089
00090 std::cout << "empty" << std::endl;
00091
00092 }
00093
00094 if( is_full() ) {
00095
00096 std::cout << "full" << std::endl;
00097
00098 }
00099
00100 std::cout << "Data : " << std::endl;
00101 for( int i = 0; i < used(); i++ ) {
00102
00103 std::cout << peek_data( i ) << std::endl;
00104
00105 }
00106
00107
00108 }
00109
00110 template < typename T >
00111 circular_buffer<T>::
00112 circular_buffer( int size ) {
00113
00114 m_size = size;
00115 m_buf = new T[m_size];
00116
00117 init();
00118
00119 }
00120
00121 template < typename T >
00122 circular_buffer<T> &
00123 circular_buffer<T>::operator=( const circular_buffer<T> &b ) {
00124
00125 init();
00126
00127 for( int i = 0; i < size() && i < b.used(); i++ ) {
00128
00129 write( b.peek_data( i ) );
00130
00131 }
00132
00133 return *this;
00134
00135 }
00136
00137 template < typename T >
00138 void
00139 circular_buffer<T>::resize( int size )
00140 {
00141
00142 int i;
00143 T *new_buf = new T[size];
00144
00145 for( i = 0; i < size && i < used(); i++ ) {
00146
00147 new_buf[i] = peek_data( i );
00148
00149 }
00150
00151 delete [] m_buf;
00152
00153 m_size = size;
00154 m_ri = 0;
00155 m_wi = i % m_size;
00156 m_used = i;
00157 m_free = m_size - m_used;
00158
00159 m_buf = new_buf;
00160
00161 }
00162
00163
00164 template < typename T >
00165 void
00166 circular_buffer<T>::init() {
00167
00168 m_free = m_size;
00169 m_used = 0;
00170 m_ri = 0;
00171 m_wi = 0;
00172
00173 }
00174
00175 template < typename T >
00176 void
00177 circular_buffer<T>::copy( const circular_buffer<T> &b )
00178 {
00179
00180 m_size = b.m_size;
00181 m_buf = b.m_buf;
00182 m_free = b.m_free;
00183 m_used = b.m_used;
00184 m_ri = b.m_ri;
00185 m_wi = b.m_wi;
00186
00187 }
00188
00189 template < typename T >
00190 const T &
00191 circular_buffer<T>::read()
00192 {
00193
00194 const T &t = read_data();
00195
00196 increment_read_pos();
00197
00198 return t;
00199
00200 }
00201
00202 template < typename T >
00203 void
00204 circular_buffer<T>::write( const T &t )
00205 {
00206
00207 write_data() = t;
00208 increment_write_pos();
00209
00210 }
00211
00212
00213 template < typename T >
00214 void
00215 circular_buffer<T>::increment_write_pos( int i ) {
00216
00217 m_wi = ( m_wi + i ) % m_size;
00218 m_used += i;
00219 m_free -= i;
00220
00221 }
00222
00223 template < typename T >
00224 void
00225 circular_buffer<T>::increment_read_pos( int i ) {
00226
00227 m_ri = ( m_ri + i ) % m_size;
00228 m_used -= i;
00229 m_free += i;
00230
00231 }
00232
00233 }
00234
00235 #endif
00236