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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef Array_h
00040 #define Array_h
00041
00042
00043 #include "Primitives.h"
00044
00045
00046
00047
00048 namespace hxa7241_general
00049 {
00050 using namespace hxa7241;
00051
00052
00062 template<class TYPE>
00063 class Array
00064 {
00066 public:
00067 Array();
00068 explicit Array( dword length );
00069
00070 ~Array();
00071 Array( const Array& );
00072 Array& operator=( const Array& );
00073
00074
00076 void setLength( dword length );
00077
00078 void swap( Array& );
00079 void append( const TYPE& );
00080 void remove( int index );
00081
00082 void zeroStorage();
00083
00084 TYPE* getStorage();
00085 TYPE& operator[]( int index );
00086
00087
00089 dword getLength() const;
00090 bool isEmpty() const;
00091 static dword getMaxLength();
00092
00093 const TYPE* getStorage() const;
00094 const TYPE& operator[]( int index ) const;
00095
00096
00098 protected:
00099 void assign( const Array<TYPE>& );
00100
00101 void acquireStorage( dword length,
00102 bool isCopied );
00103
00104 static void copyObjects( TYPE* lValStart,
00105 const TYPE* rValStart,
00106 dword length );
00107
00108
00110 private:
00111 TYPE* pStorage_m;
00112 dword length_m;
00113 };
00114
00115
00116
00117
00118
00119
00120
00121
00123 template<class TYPE>
00124 Array<TYPE>::Array()
00125 : pStorage_m( 0 )
00126 , length_m ( 0 )
00127 {
00128 }
00129
00130
00131 template<class TYPE>
00132 Array<TYPE>::Array
00133 (
00134 const dword length
00135 )
00136 : pStorage_m( 0 )
00137 , length_m ( 0 )
00138 {
00139 Array<TYPE>::setLength( length );
00140 }
00141
00142
00143 template<class TYPE>
00144 Array<TYPE>::~Array()
00145 {
00146 delete[] pStorage_m;
00147 }
00148
00149
00150 template<class TYPE>
00151 Array<TYPE>::Array
00152 (
00153 const Array<TYPE>& other
00154 )
00155 : pStorage_m( 0 )
00156 , length_m ( 0 )
00157 {
00158 Array<TYPE>::assign( other );
00159 }
00160
00161
00162 template<class TYPE>
00163 Array<TYPE>& Array<TYPE>::operator=
00164 (
00165 const Array<TYPE>& other
00166 )
00167 {
00168 assign( other );
00169
00170 return *this;
00171 }
00172
00173
00174
00175
00177 template<class TYPE>
00178 void Array<TYPE>::setLength
00179 (
00180 const dword length
00181 )
00182 {
00183 acquireStorage( length, false );
00184 }
00185
00186
00187 template<class TYPE>
00188 void Array<TYPE>::swap
00189 (
00190 Array<TYPE>& other
00191 )
00192 {
00193 TYPE*const tmpM = pStorage_m;
00194 pStorage_m = other.pStorage_m;
00195 other.pStorage_m = tmpM;
00196
00197 const dword tmpL = length_m;
00198 length_m = other.length_m;
00199 other.length_m = tmpL;
00200 }
00201
00202
00203 template<class TYPE>
00204 void Array<TYPE>::append
00205 (
00206 const TYPE& element
00207 )
00208 {
00209
00210 acquireStorage( length_m + 1, true );
00211
00212
00213 *(pStorage_m + length_m - 1) = element;
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 }
00226
00227
00228 template<class TYPE>
00229 void Array<TYPE>::remove
00230 (
00231 const int index
00232 )
00233 {
00234
00235 if( (index >= 0) & (index < length_m) )
00236 {
00237
00238 Array<TYPE> newArray( length_m - 1 );
00239
00240
00241 {
00242 TYPE* pDestination = newArray.pStorage_m;
00243 TYPE* pEnd = pDestination + newArray.length_m;
00244 const TYPE* pSource = pStorage_m;
00245 const TYPE* pIndex = pSource + index;
00246 while( pDestination < pEnd )
00247 {
00248 pSource += static_cast<dword>(pSource == pIndex);
00249 *(pDestination++) = *(pSource++);
00250 }
00251 }
00252
00253
00254 swap( newArray );
00255 }
00256 }
00257
00258
00259 template<class TYPE>
00260 void Array<TYPE>::zeroStorage()
00261 {
00262 for( dword i = length_m; i-- > 0; )
00263 {
00264 pStorage_m[ i ] = TYPE();
00265 }
00266 }
00267
00268
00269 template<class TYPE>
00270 inline
00271 TYPE* Array<TYPE>::getStorage()
00272 {
00273 return pStorage_m;
00274 }
00275
00276
00277 template<class TYPE>
00278 inline
00279 TYPE& Array<TYPE>::operator[]
00280 (
00281 const int index
00282 )
00283 {
00284 return pStorage_m[ index ];
00285 }
00286
00287
00288
00289
00291 template<class TYPE>
00292 inline
00293 dword Array<TYPE>::getLength() const
00294 {
00295 return length_m;
00296 }
00297
00298
00299 template<class TYPE>
00300 inline
00301 bool Array<TYPE>::isEmpty() const
00302 {
00303 return 0 == length_m;
00304 }
00305
00306
00307 template<class TYPE>
00308 inline
00309 dword Array<TYPE>::getMaxLength()
00310 {
00311 return DWORD_MAX;
00312 }
00313
00314
00315 template<class TYPE>
00316 inline
00317 const TYPE* Array<TYPE>::getStorage() const
00318 {
00319 return pStorage_m;
00320 }
00321
00322
00323 template<class TYPE>
00324 inline
00325 const TYPE& Array<TYPE>::operator[]
00326 (
00327 const int index
00328 ) const
00329 {
00330 return pStorage_m[ index ];
00331 }
00332
00333
00334
00335
00337 template<class TYPE>
00338 void Array<TYPE>::assign
00339 (
00340 const Array<TYPE>& other
00341 )
00342 {
00343 if( &other != this )
00344 {
00345 acquireStorage( other.getLength(), false );
00346
00347 copyObjects( getStorage(), other.getStorage(), other.getLength() );
00348 }
00349 }
00350
00351
00352 template<class TYPE>
00353 void Array<TYPE>::acquireStorage
00354 (
00355 dword newLength,
00356 const bool isCopied
00357 )
00358 {
00359
00360 newLength = (newLength >= 0) ? newLength : 0;
00361
00362
00363 if( newLength != length_m )
00364 {
00365
00366 TYPE* pNewStorage = new TYPE[ newLength ];
00367
00368
00369 if( isCopied )
00370 {
00371 copyObjects( pNewStorage, pStorage_m,
00372 (length_m <= newLength ? length_m : newLength) );
00373 }
00374
00375
00376 delete[] pStorage_m;
00377 pStorage_m = pNewStorage;
00378 length_m = newLength;
00379 }
00380 }
00381
00382
00383 template<class TYPE>
00384 void Array<TYPE>::copyObjects
00385 (
00386 TYPE*const pDestination,
00387 const TYPE*const pSource,
00388 const dword length
00389 )
00390 {
00391 if( length >= 0 )
00392 {
00393 TYPE* pDestinationCursor = pDestination + length;
00394 const TYPE* pSourceCursor = pSource + length;
00395
00396 while( pDestinationCursor > pDestination )
00397 {
00398 *(--pDestinationCursor) = *(--pSourceCursor);
00399 }
00400 }
00401 }
00402
00403
00404 }
00405
00406
00407
00408
00409 #endif//Array_h