src/tools/tArray.h

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00023   
00024 ***************************************************************************
00025 
00026 */
00027 
00028 #ifndef ArmageTron_ARRAY_H
00029 #define ArmageTron_ARRAY_H
00030 
00031 #include "defs.h"
00032 #include <new>
00033 #include "tError.h"
00034 #include "tSafePTR.h"
00035 
00036 
00037 class GrowingArrayBase {
00038     int len;    // current logical size
00039     int size;   // current size in memory
00040     void *base; // start of memory block
00041 
00042     const GrowingArrayBase & operator=(const GrowingArrayBase &);
00043     GrowingArrayBase(GrowingArrayBase &);
00044 
00045 protected:
00046     void ResizeBase(int i,int size_of_T, bool useMalloc);
00047     void *Base() const {return base;}
00048 
00049     GrowingArrayBase(int firstsize,int size_of_T, bool useMalloc);
00050     void Delete( bool useMalloc );
00051     ~GrowingArrayBase();
00052 
00053     /*
00054     #ifdef tSAFEPTR
00055     void SetSize(int s){size=s;}
00056     void SetBase(void *b){base=b;}
00057     #endif
00058     */
00059 
00060 public:
00061     void ComplainIfFull();
00062 
00063     void SetLen(int i){len=i;}
00064     int Len()const {return len;}
00065     int  Size() const {return size;}
00066 };
00067 
00068 
00069 template<class T, bool MALLOC=false> class tArray: public GrowingArrayBase {
00070 protected:
00071     void Init(){
00072         int i;
00073         for(i=Size()-1;i>=0;i--)
00074             new(reinterpret_cast<T *>(Base())+i) T();
00075     }
00076 
00077     void resize(int i){
00078         int oldsize=Size();
00079         ResizeBase(i,sizeof(T),MALLOC);
00080         // dump(low,flow,"Array resize from " << oldsize << " to " << Size());
00081         for(i=Size()-1;i>=oldsize;i--)
00082             new(reinterpret_cast<T *>(Base())+i) T();
00083     }
00084 
00085 
00086     void Clear(){
00087         int i;
00088         for(i=Size()-1;i>=0;i--){
00089             // dump(low,flow,"i=" << i);
00090             ((reinterpret_cast<T *>(Base()))+i)->~T();
00091         }
00092         Delete(MALLOC);
00093     }
00094 
00095 
00096     void CopyFrom(const tArray &A){
00097         int i;
00098         for(i=Len()-1;i>=0;i--)
00099             new(reinterpret_cast<T *>(Base())+i) T(A(i));
00100         for(i=Len();i<Size();i++)
00101             new(reinterpret_cast<T *>(Base())+i) T();
00102     }
00103 
00104 public:
00105     void SetLen(int i){
00106         GrowingArrayBase::SetLen(i);
00107         if (i>Size()) resize(i);
00108     }
00109 
00110     ~tArray(){
00111         tERR_FLOW_LOW();
00112         Clear();
00113         Delete(MALLOC);
00114     }
00115 
00116 
00117     tArray(int firstsize=0)
00118             :GrowingArrayBase(firstsize,sizeof(T),MALLOC) {
00119         // dump(low,flow,"con:size " << firstsize);
00120         Init();
00121     };
00122 
00123 
00124     tArray(const tArray &A)
00125             :GrowingArrayBase(A.Len(),sizeof(T),MALLOC){
00126         CopyFrom(A);
00127     };
00128 
00129 
00130     T& operator[](int i) {
00131 #ifdef DEBUG
00132         if (i<0) {
00133             tERR_ERROR_INT("Range error;accesed negative element " << i );
00134         }
00135 #endif
00136         if (i>=Len())
00137             SetLen(i+1);
00138 
00139         //    dump(low,flow,"[" << i << "]" << "=" << ((T *)Base())[i] << '\n');
00140 
00141         return((reinterpret_cast<T *>(Base()))[i]);
00142     };
00143 
00144     // Allow to READ from a const object. 
00145     T const& operator[](int i) const {
00146         tASSERT( i >= 0 && i < Len() );
00147 
00148         return((reinterpret_cast<T *>(Base()))[i]);
00149     };
00150 
00151     T& operator()(int i) const{
00152         tASSERT( i >= 0 && i < Len() );
00153 
00154         return((reinterpret_cast<T *>(Base()))[i]);
00155     };
00156 
00157     T* operator+(int i) const{
00158     #ifdef DEBUG
00159         if (i<0) {tERR_ERROR_INT("Range error;accesed negative element " << i )}
00160         if (i>=Len())
00161         {tERR_ERROR_INT("Range error;accesed element "
00162                             << i <<" of maximal " <<Len())}
00163     #endif
00164 
00165         return(reinterpret_cast<T *>(Base())+i);
00166     };
00167 
00168     const tArray<T> &operator=(const tArray<T> &A){
00169 
00170         Clear();
00171         SetLen(A.Len());
00172         CopyFrom(A);
00173 
00174         return *this;
00175     };
00176 
00177     void RemoveAt( int index )
00178     {
00179         int newLen = this->Len()-1;
00180         T keep = (*this)[ index ];
00181         if ( index < newLen )
00182             (*this)[ index ] = (*this)[ newLen ];
00183         this->SetLen( newLen );
00184     }
00185 
00186     bool Remove( const T& t )
00187     {
00188         for ( int i = this->Len()-1; i >= 0; --i )
00189         {
00190             if ( (*this)[i] == t )
00191             {
00192                 this->RemoveAt( i );
00193                 return true;
00194             }
00195         }
00196 
00197         return false;
00198     }
00199 
00200     void Insert( const T& t )
00201     {
00202         SetLen( this->Len()+1 );
00203         (*this)[ this->Len() -1 ] = t;
00204     }
00205 };
00206 
00207 
00208 
00209 
00210 #endif // _ARRAY_H_
00211 
00212 
00213 
00214 

Generated on Sat Mar 15 22:55:59 2008 for Armagetron Advanced by  doxygen 1.5.4