00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __Basic3DArray_h
00024 #define __Basic3DArray_h
00025
00026 #ifdef __GNUC__
00027 #pragma interface
00028 #endif
00029
00030 #ifdef NON_ANSI
00031 #include <iostream.h>
00032 #else
00033 #include <iostream>
00034 using namespace std;
00035 #endif
00036 #ifndef ANSI_HDRS
00037 #include <stdlib.h>
00038 #include <assert.h>
00039 #else
00040 #include <cassert>
00041 #include <cstdlib>
00042 #endif
00043 #include "_generic.h"
00044 #include "BasicArray.h"
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #if !defined(ThreeDArraySanityChecking)
00059 #define ThreeDArraySanityChecking 1
00060 #endif
00061
00062 template <class T>
00063 class UTILIB_API Basic3DArray;
00064
00065 template <class T>
00066 class UTILIB_API Simple3DArray;
00067
00068 template <class T>
00069 class UTILIB_API Num3DArray;
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 template <class T>
00082 class UTILIB_API Basic3DArrayRep {
00083
00084 friend class Basic3DArray<T>;
00085 friend class Simple3DArray<T>;
00086 friend class Num3DArray<T>;
00087
00088 protected:
00089
00090 Basic3DArrayRep() {ref=1; Nrows=0; Ncols=0; Data=0;}
00091 T** Data;
00092 int ref;
00093 size_type Nrows;
00094 size_type Ncols;
00095 EnumDataOwned own_data;
00096 EnumDataOwned own_ptrs;
00097
00098 };
00099
00100
00101
00102
00103
00104
00105 template <class T>
00106 class UTILIB_API Basic3DArray
00107 {
00108 public:
00109
00110 Basic3DArray()
00111 {construct(0,0,0,(T*)0);}
00112 Basic3DArray(const BasicArray<T>& array, const size_type nrows=1,
00113 const EnumDataOwned own=DataNotOwned)
00114 {construct(nrows,array.size()/nrows,array,own);}
00115 Basic3DArray(const size_type nrows, const size_type ncols, const size_type ndeep, T *d=((T*)0),
00116 const EnumDataOwned own=DataNotOwned)
00117 {construct(nrows,ncols,ndeep,d,own);}
00118 Basic3DArray(const size_type nrows, const size_type ncols, const BasicArray<T>& array,
00119 const EnumDataOwned own=DataNotOwned)
00120 {construct(nrows,ncols,array.size(),array.data(),own);}
00121 Basic3DArray(const Basic3DArray& array)
00122 {construct(array.nrows(),array.ncols(),array.array.data(),
00123 AcquireOwnership);}
00124
00125 virtual ~Basic3DArray()
00126 {free();}
00127
00128 int resize(const size_type nrows, const size_type ncols);
00129 size_type nrows() const
00130 {return a->Nrows;}
00131 size_type ncols() const
00132 {return a->Ncols;}
00133 operator T** () const
00134 {return a->Data;}
00135 T** data() const
00136 {return a->Data;}
00137 int nrefs() const
00138 {return a->ref;}
00139 T* operator[](const size_type );
00140 const T* operator[](const size_type ) const;
00141 T& operator()(const size_type row, const size_type col);
00142 const T& operator()(const size_type row, const size_type col) const;
00143
00144 Basic3DArray<T>& operator=(const Basic3DArray<T>& array);
00145 Basic3DArray<T>& operator&=(const Basic3DArray<T>& array);
00146 Basic3DArray<T>& operator<<(const Basic3DArray<T>& array);
00147 Basic3DArray<T>& operator=(const T& val);
00148 Basic3DArray<T>& operator=(const BasicArray<T>& val);
00149
00150 Basic3DArray<T>& set_data(const size_type len, T* data,
00151 const EnumDataOwned o=DataNotOwned);
00152 Basic3DArray<T>& set_data(const BasicArray<T>& array,
00153 const EnumDataOwned o=DataNotOwned)
00154 {return set_data(array.size(),array,o);}
00155
00156
00157
00158
00159
00160
00161 protected:
00162
00163 Basic3DArrayRep<T>* a;
00164
00165 void construct(const size_type nrows, const size_type ncols, const size_type ndeep, T *d,
00166 const EnumDataOwned o=DataNotOwned);
00167 void construct(const size_type nrows, const size_type ncols, const size_type ndeep, T** d,
00168 const EnumDataOwned o=DataNotOwned);
00169 void free();
00170
00171 };
00172
00173
00174 template <class T>
00175 inline T* Basic3DArray<T>::operator[](const size_type idx)
00176 {
00177 #if (ThreeDArraySanityChecking==1)
00178 if ((idx < 0) || (idx >= a->Nrows))
00179 ErrAbort(errmsg("Basic3DArray<T>::operator[] : iterator out of range. idx=%d len=%d",idx,a->Nrows));
00180 #endif
00181
00182 return a->Data[idx];
00183 }
00184
00185
00186 template <class T>
00187 inline const T* Basic3DArray<T>::operator[](const size_type idx) const
00188 {
00189 #if (ThreeDArraySanityChecking==1)
00190 if ((idx < 0) || (idx >= a->Nrows))
00191 ErrAbort(errmsg("Basic3DArray<T>::operator[] : iterator out of range. idx=%d len=%d",idx,a->Nrows));
00192 #endif
00193
00194 return a->Data[idx];
00195 }
00196
00197
00198 template <class T>
00199 inline T& Basic3DArray<T>::operator()(const size_type row, const size_type col)
00200 {
00201 #if (ThreeDArraySanityChecking==1)
00202 if ((row < 0) || (row >= a->Nrows) || (col < 0) || (col >= a->Ncols))
00203 ErrAbort(errmsg("Basic3DArray<T>::operator() : iterator out of range. %dx%d not in %dx%d",row,col,a->Nrows,a->Ncols));
00204 #endif
00205
00206 return a->Data[row][col];
00207 }
00208
00209
00210 template <class T>
00211 inline const T& Basic3DArray<T>::operator()(const size_type row, const size_type col) const
00212 {
00213 #if (ThreeDArraySanityChecking==1)
00214 if ((row < 0) || (row >= a->Nrows) || (col < 0) || (col >= a->Ncols))
00215 ErrAbort(errmsg("Basic3DArray<T>::operator() : iterator out of range. %dx%d not in %dx%d",row,col,a->Nrows,a->Ncols));
00216 #endif
00217
00218 return a->Data[row][col];
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 template <class T>
00230 void Basic3DArray<T>::construct(const size_type nrows, const size_type ncols,
00231 const size_type ndeep, T * d, const EnumDataOwned o)
00232 {
00233 a = new Basic3DArrayRep<T>;
00234 assert(a != 0);
00235
00236 a->Nrows = nrows;
00237 a->Ncols = ncols;
00238 a->Ndeep = ndeep;
00239 if (d == NULL) {
00240 if (nrows > 0) {
00241 a->Data = new T** [nrows] ;
00242 assert(a != 0);
00243 for (size_type i=0; i<nrows; i++) {
00244 a->Data[i] = new T* [ncols] ;
00245 for (size_type j=0; j<ncols; j++) {
00246 a->Data[i][j] = new T [ndeep] ;
00247 assert(a->Data[i][j] != 0);
00248 }
00249 assert(a->Data[i] != 0);
00250 }
00251 }
00252 else
00253 a->Data = NULL;
00254 a->own_ptrs = AcquireOwnership;
00255 a->own_data = AcquireOwnership;
00256 }
00257
00258 else {
00259 if (o == AcquireOwnership) {
00260 if (nrows > 0) {
00261 a->Data = new T** [nrows] ;
00262 assert(a != 0);
00263 for (size_type i=0; i<nrows; i++) {
00264 a->Data[i] = new T* [ncols] ;
00265 for (size_type j=0; j<ncols; j++) {
00266 a->Data[i][j] = new T [ndeep] ;
00267 assert(a->Data[i][j] != 0);
00268 }
00269 assert(a->Data[i] != 0);
00270 }
00271
00272 size_type ndx=0;
00273 for (size_type ii=0; ii<nrows; ii++)
00274 for (size_type jj=0; jj<ncols; jj++)
00275 for (size_type kk=0; kk<ndeep; kk++)
00276 a->Data[ii][jj][kk] = d[ndx++];
00277 }
00278 else
00279 a->Data = NULL;
00280 a->own_ptrs = AcquireOwnership;
00281 a->own_data = AcquireOwnership;
00282 }
00283 else {
00284 if (nrows > 0) {
00285 a->Data = new T** [nrows] ;
00286 assert(a->Data != 0);
00287 for (size_type i=0; i<nrows; i++) {
00288 a->Data[i] = new T* [ncols] ;
00289 assert(a->Data[i] != 0);
00290 }
00291 T* tmp = d;
00292 for (size_type i=0; i<ncols; i++) {
00293 a->Data[i] = tmp;
00294 tmp+= ncols;
00295 }
00296 }
00297 else
00298 a->Data = NULL;
00299 a->own_ptrs = AcquireOwnership;
00300 a->own_data = DataNotOwned;
00301 }
00302 }
00303 }
00304
00305
00306 template <class T>
00307 void Basic3DArray<T>::construct(const size_type nrows, const size_type ncols, const size_type ndeep, T **d,
00308 const EnumDataOwned o)
00309 {
00310 a = new Basic3DArrayRep<T>;
00311 assert(a != 0);
00312
00313 a->Nrows = nrows;
00314 a->Ncols = ncols;
00315 if (d == NULL) {
00316 if (nrows > 0) {
00317 a->Data = new T** [nrows] ;
00318 assert(a != 0);
00319 for (size_type i=0; i<nrows; i++) {
00320 a->Data[i] = new T* [ncols] ;
00321 for (size_type j=0; j<ncols; j++) {
00322 a->Data[i][j] = new T [ndeep] ;
00323 assert(a->Data[i][j] != 0);
00324 }
00325 assert(a->Data[i] != 0);
00326 }
00327 }
00328 else
00329 a->Data = NULL;
00330 a->own_ptrs = AcquireOwnership;
00331 a->own_data = AcquireOwnership;
00332 }
00333
00334 else {
00335 if (o == AcquireOwnership) {
00336 if (nrows > 0) {
00337 a->Data = new T** [nrows] ;
00338 assert(a->Data != 0);
00339 for (size_type i=0; i<nrows; i++) {
00340 a->Data[i] = new T* [ncols] ;
00341 for (size_type j=0; j<ncols; j++) {
00342 a->Data[i][j] = new T [ndeep] ;
00343 assert(a->Data[i][j] != 0);
00344 }
00345 assert(a->Data[i] != 0);
00346 }
00347
00348 for (size_type ii=0; ii<nrows; ii++)
00349 for (size_type jj=0; jj<ncols; jj++)
00350 a->Data[ii][jj] = d[ii][jj];
00351 }
00352 else
00353 a->Data = NULL;
00354 a->own_ptrs = AcquireOwnership;
00355 a->own_data = AcquireOwnership;
00356 }
00357 else {
00358 a->Data=d;
00359 a->own_ptrs = DataNotOwned;
00360 a->own_data = DataNotOwned;
00361 }
00362 }
00363 }
00364
00365
00366 template <class T>
00367 void Basic3DArray<T>::free()
00368 {
00369 if (--a->ref == 0) {
00370 if ((a->Data) && (a->Nrows>0)) {
00371 if (a->own_data && (a->Ncols > 0)) {
00372 for (size_type i=0; i<a->Nrows; i++) {
00373 for (size_type j=0; j<a->Ncols; j++)
00374 if (a->Ndeep > 0) delete [] a->Data[i][j];
00375 delete [] a->Data[i];
00376 }
00377 }
00378 if (a->own_ptrs)
00379 delete [] a->Data;
00380 }
00381 delete a;
00382 }
00383 }
00384
00385
00386 template <class T>
00387 int Basic3DArray<T>::resize(const size_type nrows, const size_type ncols)
00388 {
00389
00390
00391
00392 if ((ncols == a->Ncols) && (nrows == a->Nrows) && (ndeep == a->Ndeep))
00393 return OK;
00394
00395
00396
00397
00398 if ((ncols != a->Ncols) && (nrows != a->Nrows) && (ndeep != a->Ndeep)) {
00399
00400
00401
00402 if ((a->Data) && (a->Nrows>0)) {
00403 if (a->own_data && (a->Ncols > 0)) {
00404 for (size_type i=0; i<a->Nrows; i++) {
00405 for (size_type j=0; j<a->Ncols; j++)
00406 if (a->Ndeep > 0) delete [] a->Data[i][j];
00407 delete [] a->Data[i];
00408 }
00409 }
00410 if (a->own_ptrs)
00411 delete [] a->Data;
00412 }
00413
00414
00415
00416 if (nrows > 0) {
00417 a->Data = new T** [nrows] ;
00418 assert(a != 0);
00419 for (size_type i=0; i<nrows; i++) {
00420 a->Data[i] = new T* [ncols] ;
00421 for (size_type j=0; j<ncols; j++) {
00422 a->Data[i][j] = new T [ndeep] ;
00423 assert(a->Data[i][j] != 0);
00424 }
00425 assert(a->Data[i] != 0);
00426 }
00427 }
00428 else
00429 a->Data = NULL;
00430 a->own_ptrs = AcquireOwnership;
00431 a->own_data = AcquireOwnership;
00432 a->Nrows = nrows;
00433 a->Ncols = ncols;
00434 a->Ndeep = ndeep;
00435 return OK;
00436 }
00437
00438
00439
00440
00441 if (nrows != a->Nrows) {
00442 T **d=NULL;
00443 if (nrows > 0) {
00444 d = new T* [nrows];
00445 assert(d != 0);
00446
00447
00448
00449
00450 if (a->Nrows > 0) {
00451 for (size_type i=0; i<MIN(nrows,a->Nrows); i++)
00452 d[i] = a->Data[i];
00453 }
00454 }
00455
00456 if (a->Data && a->own_ptrs && (a->Nrows > 0))
00457 delete [] a->Data;
00458
00459 a->Data = d;
00460 a->Nrows = nrows;
00461 }
00462
00463
00464
00465
00466 if (ncols != a->Ncols) {
00467 if (ncols > 0) {
00468 for (size_type j=0; j<a->Nrows; j++) {
00469 T* d=NULL;
00470 d = new T [ncols];
00471 assert(d != 0);
00472
00473
00474
00475
00476 if (a->Ncols > 0) {
00477 for (size_type i=0; i<MIN(ncols,a->Ncols); i++)
00478 d[i] = a->Data[j][i];
00479 }
00480 if (a->Data && a->own_data && (a->Ncols > 0))
00481 delete [] a->Data[j];
00482 a->Data[j] = d;
00483 }
00484 }
00485 else
00486 if (a->Data && a->own_data && (a->Ncols > 0))
00487 for (size_type i=0; i<a->Nrows; i++) {
00488 delete [] a->Data[i];
00489 a->Data[i] = NULL;
00490 }
00491
00492 a->Ncols = ncols;
00493 }
00494
00495 return OK;
00496 }
00497
00498
00499 template <class T>
00500 Basic3DArray<T>& Basic3DArray<T>::operator=(const Basic3DArray<T>& array)
00501 {
00502
00503
00504 if (this != &array) {
00505 free();
00506 construct(array.nrows(),array.ncols(),array.data(),AcquireOwnership);
00507 }
00508 return *this;
00509 }
00510
00511
00512 template <class T>
00513 Basic3DArray<T>& Basic3DArray<T>::operator<<(const Basic3DArray<T>& array)
00514 {
00515 if (array.a == a)
00516 return *this;
00517 if ((array.a->Nrows != a->Nrows) || (array.a->Ncols != a->Ncols))
00518 ErrAbort(errmsg("Basic3DArray<T>::operator<< : Unequal vector matrices %dx%d and %dx%d.",a->Nrows,a->Ncols,array.a->Nrows,array.a->Ncols));
00519
00520 for (size_type i=0; i<a->Nrows; i++)
00521 for (size_type j=0; j<a->Ncols; j++)
00522 a->Data[i][j] = array.a->Data[i][j];
00523
00524 return *this;
00525 }
00526
00527
00528
00529 template <class T>
00530 Basic3DArray<T>& Basic3DArray<T>::operator&=(const Basic3DArray<T>& array)
00531 {
00532 if (array.a == a) return *this;
00533
00534 free();
00535 a = array.a;
00536 a->ref++;
00537 return *this;
00538 }
00539
00540
00541
00542 template <class T>
00543 Basic3DArray<T>& Basic3DArray<T>::operator=(const T& val)
00544 {
00545 for (size_type i=0; i<a->Nrows; i++)
00546 for (size_type j=0; j<a->Ncols; j++)
00547 a->Data[i][j] = ( T ) val;
00548 return *this;
00549 }
00550
00551
00552
00553 template <class T>
00554 Basic3DArray<T>& Basic3DArray<T>::operator=(const BasicArray<T>& val)
00555 {
00556 if (a->Ncols != val.size())
00557 ErrAbort(errmsg("Basic3DArray<T>::operator= : Array length does not equal the 3DArray columns %d and %d",val.size(),a->Ncols));
00558
00559 for (size_type i=0; i<a->Nrows; i++)
00560 for (size_type j=0; j<a->Ncols; j++)
00561 a->Data[i][j] = val[j];
00562 return *this;
00563 }
00564
00565 template <class T>
00566 Basic3DArray<T>& Basic3DArray<T>::set_data(const size_type len, T * data, const EnumDataOwned o)
00567 {
00568 #if TwoDArraySanityChecking==1
00569 if ( (nrows()*ncols()) != len)
00570 ErrAbort(errmsg("Basic3DArray<T>::set_data : bad vector size %d != %d.",
00571 (nrows()*ncols()),len));
00572 #endif
00573
00574 if (a->own_data && (a->Ncols > 0)) {
00575 for (size_type i=0; i<a->Nrows; i++)
00576 delete [] a->Data[i];
00577 }
00578 size_type ndx=0;
00579 for (size_type i=0; i<a->Nrows; i++) {
00580 a->Data[i] = &(data[ndx]);
00581 ndx += a->Ncols;
00582 }
00583
00584
00585
00586
00587 a->own_data = DataNotOwned;
00588 return *this;
00589 }
00590
00591 #endif