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