00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
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;    
00039     int size;   
00040     void *base; 
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 
00055 
00056 
00057 
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         
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             
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         
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         
00140 
00141         return((reinterpret_cast<T *>(Base()))[i]);
00142     };
00143 
00144     
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