• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

spl/collection/CircularArray.h

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #ifndef _tcirculararray_h
00018 #define _tcirculararray_h
00019 
00020 #include <spl/types.h>
00021 #include <spl/Debug.h>
00022 
00023 #ifdef _WINDOWS
00024 #include <spl/configwin32.h>
00025 #else
00026 #include <spl/autoconf/config.h>
00027 #endif
00028 
00029 #include <spl/Exception.h>
00030 #include <spl/Memory.h>
00031 
00037 class CircularArrayException : Exception
00038 {
00039 public:
00040         CircularArrayException(const char *msg);
00041 };
00042 
00044 template<typename T>
00045 class CircularArray: public IMemoryValidate
00046 {
00047 protected:
00048         int m_size;
00049         T *m_array;
00050         int m_writepos;
00051         int m_readpos;
00052 
00053 public:
00054         CircularArray( int size ) : m_writepos(0), m_readpos(0)
00055         {
00056                 m_size = size;
00057                 m_array = new T[size];
00058         }
00059 
00060         CircularArray( const CircularArray<T>& ar )
00061         : m_writepos(ar.m_writepos), m_readpos(ar.m_readpos), m_size(ar.m_size)
00062         {
00063                 m_array = new T[m_size];
00064                 for ( int x = 0; x < m_size; x++ )
00065                 {
00066                         m_array[x] = ar.m_array[x];
00067                 }
00068         }
00069 
00070         virtual ~CircularArray()
00071         {
00072                 delete m_array;
00073         }
00074 
00075         void Write( T data )
00076         {
00077                 ASSERT_MEM( m_array, m_size*sizeof(T) );
00078                 if ( m_size == m_writepos )
00079                 {
00080                         m_writepos = 0;
00081                 }
00082                 m_array[m_writepos++] = data;
00083                 if ( m_writepos == m_readpos )
00084                 {
00085                         throw new CircularArrayException("insert overwrote read pos -- make array larger");
00086                 }
00087         }
00088 
00089         void Write( T *data, int start, int len )
00090         {
00091                 int end = len + start;
00092                 for ( int x = start; x < end; x++ )
00093                 {
00094                         write( data[x] );
00095                 }
00096         }
00097 
00098         void Read( T *data )
00099         {
00100                 ASSERT_MEM( m_array, m_size*sizeof(T) );
00101                 if ( m_readpos == m_writepos )
00102                 {
00103                         CircularArrayException("EOF");
00104                 }
00105                 if ( m_readpos == m_size )
00106                 {
00107                         m_readpos = 0;
00108                 }
00109                 *data = m_array[m_readpos++];
00110         }
00111 
00112         void Read( T *data, int start, int len )
00113         {
00114                 int end = len + start;
00115                 for ( int x = start; x < end; x++ )
00116                 {
00117                         Read( &data[x] );
00118                 }
00119         }
00120 
00121         int Count() const
00122         {
00123                 if ( m_writepos >= m_readpos )
00124                 {
00125                         return m_writepos - m_readpos;
00126                 }
00127                 return m_size - m_readpos + m_writepos;
00128         }
00129 
00130         T Peek( int offset ) const
00131         {
00132                 ASSERT_MEM( m_array, m_size*sizeof(T) );
00133                 int pos = m_readpos + offset;
00134                 if ( offset == m_writepos )
00135                 {
00136                         CircularArrayException("EOF");
00137                 }
00138                 if ( pos >= m_size )
00139                 {
00140                          pos -= m_size;
00141                 }
00142                 return m_array[pos];
00143         }
00144 
00145         int LocateElement( T item ) const
00146         {
00147                 int cnt = Count();
00148                 for ( int x = 0; x < cnt; x++ )
00149                 {
00150                         if ( Peek(x) == item )
00151                         {
00152                                 return x;
00153                         }
00154                 }
00155                 return -1;
00156         }
00157 
00158         CircularArray<T>& operator =( const CircularArray<T>& ar )
00159         {
00160                 delete[] m_array;
00161 
00162                 m_writepos = ar.m_writepos;
00163                 m_readpos = ar.m_readpos;
00164                 m_size = ar.m_size;
00165 
00166                 m_array = new T[m_size];
00167                 for ( int x = 0; x < m_size; x++ )
00168                 {
00169                         m_array[x] = ar.m_array[x];
00170                 }
00171 
00172                 return *this;
00173         }
00174 
00175 #ifdef DEBUG
00176         virtual void ValidateMem() const
00177         {
00178                 ASSERT_MEM(m_array, m_size*sizeof(T));
00179         }
00180 
00181         virtual void CheckMem() const
00182         {
00183                 DEBUG_NOTE_MEM_ALLOCATION(m_array);
00184                 for ( int x = 0; x < m_size; x++ )
00185                 {
00186                         ValidateType(m_array[x]);
00187                 }
00188         }
00189 #endif
00190 };
00191 
00194 #endif