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

spl/collection/Vector.h

Go to the documentation of this file.
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  */
00018 #ifndef _tvector_h
00019 #define _tvector_h
00020 
00021 #include <spl/types.h>
00022 #include <spl/Debug.h>
00023 
00024 #include <spl/collection/Array.h>
00025 #include <spl/Exception.h>
00026 #include <spl/collection/IEnumerable.h>
00027 #include <spl/IIterator.h>
00028 #include <spl/Memory.h>
00029 #include <spl/RefCountPtr.h>
00030 
00040 template<typename T>
00041 class Vector : public IEnumerable<T>
00042 {
00043 protected:
00044         T *m_data;
00045         int m_pos;              
00046         int m_size;             
00048         virtual RefCountPtr<IIterator<T> > IteratorPtr()
00049         {
00050                 return RefCountPtr<IIterator<T> >(new Iterator(this));
00051         }
00052 
00053 public:
00054         class Iterator : public IIterator<T>
00055         {
00056         private:
00057                 const Vector<T> *m_ap;
00058                 int m_pos;
00059 
00060         public:
00061                 Iterator(const Vector<T> *ap)
00062                 : m_ap(ap), m_pos(-1)
00063                 {
00064                 }
00065 
00066                 Iterator(const Iterator& vi)
00067                 : m_ap(vi.m_ap), m_pos(vi.m_pos)
00068                 {
00069                 }
00070 
00071                 virtual bool Next()
00072                 {
00073                         if (++m_pos >= m_ap->Count())
00074                         {
00075                                 return false;
00076                         }
00077                         return true;
00078                 }
00079 
00080                 virtual bool Prev()
00081                 {
00082                         if (--m_pos < 0)
00083                         {
00084                                 return false;
00085                         }
00086                         return true;
00087                 }
00088 
00089                 virtual T Current()
00090                 {
00091                         return m_ap->ElementAt(m_pos);
00092                 }
00093 
00094                 virtual T& CurrentRef()
00095                 {
00096                         return m_ap->ElementAtRef(m_pos);
00097                 }       
00098         };
00099 
00103         Vector(int count = 10) 
00104         : m_pos(0), m_size(count)
00105         {
00106                 if ( NULL == (m_data = new T[m_size]) )
00107                 {
00108                         throw OutOfMemoryException();
00109                 }
00110                 //memset(m_data, 0, m_size * sizeof(T));
00111 #ifdef DEBUG
00112                 // The debug memory checks need this zero'ed for native types of T
00113                 for ( int x = 0; x < m_size; x++ )
00114                 {
00115                         m_data[x] = T();
00116                 }
00117 #endif
00118         }
00119 
00120         Vector(const Vector& v) : m_pos(v.m_pos), m_size(v.m_size)
00121         {
00122                 m_data = new T[m_size];
00123 
00124                 for ( int x = 0; x < m_size; x++ )
00125                 {
00126                         m_data[x] = v.m_data[x];
00127                 }
00128         }
00129 
00130         virtual ~Vector()
00131         {
00132                 ASSERT_MEM( m_data, sizeof(T) * m_size );
00133                 delete[] m_data;
00134         }
00135 
00136         Vector& operator =(const Vector& v)
00137         {
00138                 Vector<T>::ValidateMem();
00139 
00140                 delete[] m_data;
00141 
00142                 m_pos = v.m_pos;
00143                 m_size = v.m_size;
00144                 m_data = new T[m_size];
00145 
00146                 for ( int x = 0; x < m_size; x++ )
00147                 {
00148                         m_data[x] = v.m_data[x];
00149                 }
00150 
00151                 return *this;
00152         }
00153 
00154         inline Iterator Begin() const
00155         {
00156                 return Iterator(this);
00157         }
00158 
00164         inline void Add( T item )
00165         {
00166                 if ( m_pos == m_size )
00167                 {
00168                         Extend(m_size*2);
00169                 }
00170                 m_data[m_pos++] = item;
00171         }
00172 
00173         void AddRange(const Array<T>& a, const int offset, const int len)
00174         {
00175                 for ( int x = 0; x + offset < a.Length() && x < len; x++ )
00176                 {
00177                         Add(a[x+offset]);
00178                 }
00179         }
00180 
00181         inline void AddRange(const Array<T>& a, const int len)
00182         {
00183                 AddRange(a, 0, len);
00184         }
00185 
00186         inline void AddRange(const Array<T>& a)
00187         {
00188                 AddRange(a, 0, a.Length());
00189         }
00190 
00191         void AddRange(const Vector<T>& v)
00192         {
00193                 for (int x = 0; x < v.Count(); x++)
00194                 {
00195                         Add(v.ElementAt(x));
00196                 }
00197         }
00198 
00199         void AddRangeWithPad(const Array<T>& a, int count)
00200         {
00201                 for (int x = 0; x < count; x++)
00202                 {
00203                         if (x < a.Length())
00204                         {
00205                                 Add(a[x]);
00206                         }
00207                         else
00208                         {
00209                                 Add(T());
00210                         }
00211                 }
00212         }
00213 
00214         void AddRangeWithLeadingPad(Array<T>& a, int count)
00215         {
00216                 int diff = count - a.Length();
00217                 ASSERT(diff >= 0);
00218 
00219                 for (int x = 0; x < count; x++)
00220                 {
00221                         if (x >= diff)
00222                         {
00223                                 Add(a[x - diff]);
00224                         }
00225                         else
00226                         {
00227                                 Add(T());
00228                         }
00229                 }
00230         }
00231 
00239         void SetElementAt( T item, int pos )
00240         {
00241                 if ( pos >= m_size )
00242                 {
00243                         ExtendTo(pos+1);
00244                 }
00245                 if ( pos >= m_pos )
00246                 {
00247                         m_pos = pos + 1;
00248                 }
00249                 m_data[pos] = item;
00250         }
00251 
00259         void Insert( T item, int pos )
00260         {
00261                 if ( m_pos+1 >= m_size )
00262                 {
00263                         ExtendTo(m_size+10);
00264                 }
00265                 memcpy(&m_data[pos+1], &m_data[pos], (m_pos - pos)*sizeof(T));
00266                 m_data[pos] = item;
00267                 m_pos++;
00268                 ASSERT_PTR( &m_data[m_pos] );
00269                 ASSERT_MEM( m_data, sizeof(T) * m_size );
00270         }
00271 
00277         inline T ElementAt( const int pos ) const
00278         {
00279                 ASSERT( pos >= 0 );
00280                 ASSERT( pos < m_pos );
00281                 ASSERT_MEM( m_data, sizeof(T) * m_size );
00282                 if ( pos >= m_pos || 0 > pos )
00283                 {
00284                         throw IndexOutOfBoundsException();
00285                 }
00286                 return m_data[pos];
00287         }
00288 
00294         inline T& ElementAtRef( const int pos ) const
00295         {
00296                 ASSERT( pos >= 0 );
00297                 ASSERT( pos < m_pos );
00298                 ASSERT_MEM( m_data, sizeof(T) * m_size );
00299                 if ( pos >= m_pos || 0 > pos )
00300                 {
00301                         throw IndexOutOfBoundsException();
00302                 }
00303                 return m_data[pos];
00304         }
00305 
00311         T RemoveAt( const int pos )
00312         {
00313                 if ( pos >= m_pos )
00314                 {
00315                         return T();
00316                 }
00317                 T element = ElementAt(pos);
00318                 ASSERT_MEM( m_data, sizeof(T) * m_size );
00319                 ASSERT_PTR( &m_data[pos] );
00320                 memcpy(&m_data[pos], &m_data[pos+1], (m_pos - pos)*sizeof(T));
00321                 m_pos--;
00322                 ASSERT_PTR( &m_data[m_pos] );
00323                 ASSERT_MEM( m_data, sizeof(T) * m_size );
00324                 return element;
00325         }
00326 
00327         inline T& operator[] (const int idx) const
00328         {
00329                 return ElementAtRef(idx);
00330         }
00331 
00337         void Remove( const T& item )
00338         {
00339                 int count = Count();
00340                 for ( int x = 0; x < count; x++ )
00341                 {
00342                         if ( item ==  ElementAt(x) )
00343                         {
00344                                 RemoveAt( x );
00345                                 return;
00346                         }
00347                 }
00348         }
00349 
00353         inline T Pop(  )
00354         {
00355                 ASSERT( m_pos > 0 );
00356                 if (m_pos == 0)
00357                 {
00358                         return T();
00359                 }
00360                 return m_data[--m_pos];
00361         }
00362 
00366         inline T Peek(  ) const
00367         {
00368                 ASSERT( m_pos > 0 );
00369                 if (m_pos == 0)
00370                 {
00371                         throw Exception("Stack empty");
00372                 }
00373                 return m_data[m_pos-1];
00374         }
00375 
00379         inline T& PeekRef(  ) const
00380         {
00381                 ASSERT( m_pos > 0 );
00382                 if (m_pos == 0)
00383                 {
00384                         throw Exception("Stack empty");
00385                 }
00386                 return m_data[m_pos-1];
00387         }
00388 
00393         inline void Clear()
00394         {
00395                 m_pos = 0;
00396         }
00397 
00401         inline int Count() const
00402         {
00403                 return m_pos;
00404         }
00405 
00410         Vector<T> *Copy() const
00411         {
00412                 Vector<T> *vec = new Vector<T>();
00413                 int count = Count();
00414                 for ( int x = 0; x < count; x++ )
00415                 {
00416                         vec->Add( ElementAt(x) );
00417                 }
00418                 return vec;
00419         }
00420 
00424         inline T *Data() { return m_data; }
00425 
00430         void EnsureElementTo(int size)
00431         {
00432                 if ( size <= Count() )
00433                 {
00434                         return;
00435                 }
00436                 ExtendTo(size);
00437         }
00438 
00439         void SetCount(int cnt)
00440         {
00441                 ASSERT( cnt < m_size );
00442                 m_pos = cnt;
00443         }
00444 
00445         inline RefCountPtr<Array<T> > ToArray() const
00446         {
00447                 return ToArray(Count());
00448         }
00449 
00450         inline RefCountPtr<Array<T> > ToArray(int count) const
00451         {
00452                 return RefCountPtr<Array<T> >(new Array<T>(m_data, count));
00453         }
00454 
00455 #if defined(DEBUG) || defined(_DEBUG)
00456         void CheckMem() const
00457         {
00458                 DEBUG_NOTE_MEM_ALLOCATION( m_data );
00459                 for ( int x = 0; x < m_size; x++ )
00460                 {
00461                         ValidateType( m_data[x] );
00462                 }
00463         }
00464 
00465         void ValidateMem() const
00466         {
00467                 ASSERT_MEM(m_data, sizeof(T) * m_size);
00468         }
00469 #endif
00470 
00471 protected:
00472         void ExtendTo(int index)
00473         {
00474                 ASSERT_MEM(m_data, sizeof(T) * m_size);
00475 
00476                 if (index > m_size)
00477                 {
00478                         Extend(index+1);
00479                         ASSERT_MEM(m_data, sizeof(T) * m_size);
00480                 }
00481                 ASSERT_MEM(m_data, sizeof(T) * m_size);
00482         }
00483 
00484         void Extend(int newlen)
00485         {
00486                 ASSERT_MEM(m_data, sizeof(T) * m_size);
00487 
00488                 int x;
00489                 T *newbuf;
00490 
00491                 if ((newbuf = new T[newlen]) == NULL)
00492                 {
00493                         throw OutOfMemoryException();
00494                 }
00495                 for ( x = 0; x < m_size; x++ )
00496                 {
00497                         newbuf[x] = m_data[x];
00498                 }
00499                 //memset(&newbuf[m_size], 0, (newlen - m_size) * sizeof(T));
00500 #ifdef DEBUG
00501                 // The debug memory checks need this zero'ed for native types of T
00502                 for ( x = m_size; x < newlen; x++ )
00503                 {
00504                         newbuf[x] = T();
00505                 }
00506 #endif
00507                 m_size = newlen;
00508                 delete[] m_data;
00509                 m_data = newbuf;
00510                 ASSERT_MEM(m_data, sizeof(T) * m_size);
00511         }
00512 };
00513 
00514 REGISTER_TYPEOF( 170, Vector<char> );
00515 REGISTER_TYPEOF( 171, Vector<byte> );
00516 REGISTER_TYPEOF( 172, Vector<int16> );
00517 REGISTER_TYPEOF( 173, Vector<uint16> );
00518 REGISTER_TYPEOF( 174, Vector<int32> );
00519 REGISTER_TYPEOF( 175, Vector<uint32> );
00520 REGISTER_TYPEOF( 176, Vector<int64> );
00521 REGISTER_TYPEOF( 177, Vector<uint64> );
00522 REGISTER_TYPEOF( 178, Vector<float32> );
00523 REGISTER_TYPEOF( 179, Vector<float64> );
00524 
00527 #endif