00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef _H_N1DARRAY
00012 #define _H_N1DARRAY
00013
00018
00019
00020 #include <vector>
00021
00023
00024
00025
00026
00028 #define _HP
00029
00045 template<typename stored_type>
00046 class N1DArray {
00047 private:
00048
00049 #ifdef _VOID_CHECK
00050
00053 void voidCheckDBG() {
00054 int c=0;
00055 for (int i=0; i<size; i++)
00056 if ( _storage[i] == 0 )
00057 c++;
00058 cout << "Number of stored void blocks: " << c << endl; fflush( stdout );
00059 }
00060 #endif
00061
00062 protected:
00063
00065 unsigned int size;
00066
00068 unsigned int _dimension;
00069
00071 vector< unsigned int > _sizes;
00072
00074 vector< unsigned int > _cumulative_size;
00075
00077 stored_type *_storage;
00078
00088 bool checkIndex( vector< unsigned int > index ) {
00089 if ( index.size() == _dimension ) {
00090 for ( unsigned int i=0; i<_dimension; i++ ) {
00091 if ( index[i] >= _sizes[i] || index[i] < 0) {
00092 cerr << "Warning: wrong index vector in N1DArray::checkIndex index[" << i << "] = " << index[i] << " not in [0, " << _sizes[i] << "]!" << endl;
00093 return false;
00094 } else {
00095 return true;
00096 }
00097 }
00098 }
00099 cerr << "Warning: wrong index vector size in N1DArray::checkIndex (" << index.size() << ")" << endl;
00100 return false;
00101 }
00102
00103 public:
00104
00106 class Iterator : public std::iterator<std::forward_iterator_tag, stored_type> {
00107 private:
00108
00110 unsigned int at;
00111
00113 N1DArray< stored_type > *arr;
00114
00115 public:
00116
00123 Iterator( N1DArray< stored_type > *a ) {
00124 at = 0;
00125 arr = a;
00126 }
00127
00135 Iterator( N1DArray< stored_type > *a, unsigned int b ) {
00136 at = b;
00137 arr = a;
00138 }
00139
00141 Iterator& operator=( const Iterator& other ) {
00142 at = other.at;
00143 arr = other.arr;
00144 return (*this);
00145 }
00146
00148 bool operator==( const Iterator& other ) {
00149 return ( at == other.at && arr == other.arr );
00150 }
00151
00153 bool operator!=(const Iterator& other ) {
00154 return ( at != other.at || arr != other.arr );
00155 }
00156
00158 Iterator& operator++() {
00159 at++;
00160 return (*this);
00161 }
00162
00169 stored_type operator*() {
00170
00171 return arr->_storage[ at ];
00172 }
00173
00174 };
00175
00183 Iterator begin() {
00184 return Iterator( this );
00185 }
00186
00194 Iterator end() {
00195 return Iterator( this, size );
00196 }
00197
00206 int get1D( vector< unsigned int > index ) {
00207
00208
00209 if ( !checkIndex( index ) ) {
00210 cerr << "N1DArray received bad index vector!" << endl;
00211 exit(1);
00212 }
00213
00214 unsigned int index_1d = 0;
00215
00216 #ifdef _DEBUG
00217 cout << "Index vector: < ";
00218 #endif
00219
00220
00221 for ( unsigned int i=0; i<_dimension; i++ ) {
00222 index_1d += index[i] * _cumulative_size[i];
00223
00224 #ifdef _DEBUG
00225 cout << index[i] << " ";
00226 #endif
00227 }
00228 #ifdef _DEBUG
00229 cout << "> maps to " << index_1d << "/" << size << endl;
00230 #endif
00231
00232 #ifndef _HP
00233
00234 if ( index_1d >= size ) {
00235 cerr << "1D index exceeds allocated number!" << endl;
00236 cerr << "Requested index vector: < ";
00237 for ( unsigned int i=0; i<_dimension; i++ )
00238 cerr << index[i] << " ";
00239 cerr << ">" << endl;
00240 cerr << "Size vector: < ";
00241 for ( unsigned int i=0; i<_dimension; i++ )
00242 cerr << _sizes[i] << " ";
00243 cerr << ">" << endl;
00244 cerr << "Cumulative size vector: < ";
00245 for ( unsigned int i=0; i<_dimension; i++ )
00246 cerr << _cumulative_size[i] << " ";
00247 cerr << ">" << endl;
00248 exit(1);
00249 }
00250 #endif
00251
00252 return index_1d;
00253 }
00254
00262 N1DArray( vector< unsigned int > sizes ) {
00263
00264 #ifdef _DEBUG
00265 cout << "Size vector: < ";
00266 for ( unsigned int i=0; i<sizes.size(); i++)
00267 cout << sizes[i] << " ";
00268 cout << ">" << endl; fflush( stdout );
00269 #endif
00270
00271 _dimension = sizes.size();
00272 _sizes = sizes;
00273 _cumulative_size = sizes;
00274 size = 1;
00275 for (int j=_dimension-1; j >=0; j--) {
00276 size *= _sizes[j];
00277 }
00278
00279 _storage = new stored_type[size];
00280
00281 #ifdef _DEBUG
00282 cout << "Allocated size: " << size << endl;
00283 #endif
00284
00285 _cumulative_size[0] = 1;
00286 for ( unsigned int i=1; i<_dimension; i++ ) {
00287 _cumulative_size[i] = _sizes[i-1] * _cumulative_size[i-1];
00288 #ifdef _DEBUG
00289 cout << "Sumsiz[" << i << "]=" << _cumulative_size[i] << endl;
00290 #endif
00291 }
00292
00293 #ifdef _SET_INITIAL_ZERO
00294 for (int i=0; i<size; i++)
00295 _storage[i] = 0;
00296 #endif
00297
00298 }
00299
00310 N1DArray( unsigned int x, unsigned int y, unsigned int z, unsigned int w) {
00311
00312 vector< unsigned int > v(4);
00313 v[0]=x; v[1]=y; v[2]=z; v[3]=w;
00314 this(v);
00315 }
00316
00322 ~N1DArray() {
00323 delete [] _storage;
00324 }
00325
00333 stored_type get(vector< unsigned int > index) {
00334
00335 #ifdef _VOID_CHECK
00336 voidCheckDBG();
00337 #endif
00338
00339 unsigned int index_1d = get1D(index);
00340 return _storage[index_1d];
00341 }
00342
00350 void set(vector< unsigned int > index, stored_type obj) {
00351
00352 #ifdef _VOID_CHECK
00353 voidCheckDBG();
00354 #endif
00355
00356
00357
00358 #ifdef _DEBUG
00359 cout << "N1DArray::set called with index: < ";
00360 for ( unsigned int i=0; i<index.size(); i++ )
00361 cout << index[i] << " ";
00362 cout << " >" << endl;
00363 #endif
00364
00365 unsigned int index_1d = get1D( index );
00366
00367 #ifdef _DEBUG
00368 cout << "1D location: " << index_1d << endl;
00369 #endif
00370
00371 _storage[index_1d] = obj;
00372 }
00373
00386 void resize( vector< unsigned int > sizes ) {
00387
00388 #ifdef _VOID_CHECK
00389 voidCheckDBG();
00390 #endif
00391
00392 #ifdef _DEBUG
00393 cout << "New sizes: < ";
00394 for (int i=0; i<_dimension; i++)
00395 cout << sizes[i] << " ";
00396 cout << ">" << endl;
00397 #endif
00398
00399
00400 if ( sizes.size() != _sizes.size() ) {
00401 cerr << "Cannot resize the vector dimension itself!" << endl;
00402 exit(1);
00403 }
00404
00405
00406 bool same = true;
00407 for ( unsigned int dim=0; dim<_dimension; dim++) {
00408 if ( sizes[dim] != _sizes[dim] )
00409 same = false;
00410 if ( sizes[dim] < _sizes[dim] ) {
00411 #ifdef _SMALLER_RESIZE_WARNING_ON
00412 cerr << "Cannot resize to smaller sizes (would possibly lose data)!" << endl;
00413 cerr << "Ignoring resize command (!)" << endl;
00414 #endif
00415
00416 return;
00417 }
00418 }
00419
00420
00421 if ( same )
00422 return;
00423
00424
00425 N1DArray< stored_type > *replacement = new N1DArray< stored_type >( sizes );
00426
00427 vector< unsigned int > copy_index;
00428 copy_index.resize( _dimension );
00429 for ( unsigned int i=0; i<_dimension; i++ )
00430 copy_index[i] = 0;
00431
00432
00433 while (true) {
00434 stored_type element = get( copy_index );
00435 replacement->set( copy_index, element );
00436 copy_index[0]++;
00437 for ( unsigned int i=0; i<(_dimension-1); i++ ) {
00438 if (copy_index[i] == _sizes[i]) {
00439 copy_index[i] = 0;
00440 copy_index[i+1]++;
00441 }
00442 }
00443 if ( copy_index[_dimension-1] == _sizes[_dimension-1] )
00444 break;
00445 }
00446
00447
00448 delete [] _storage;
00449 _sizes.clear();
00450 _cumulative_size.clear();
00451
00452
00453
00454 size = replacement->size;
00455 _storage = replacement->_storage;
00456 _sizes = replacement->_sizes;
00457 _cumulative_size = replacement->_cumulative_size;
00458
00459 #ifdef _VOID_CHECK
00460 voidCheckDBG();
00461 #endif
00462
00463 }
00464
00465 };
00466
00467 #endif