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