arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

arrayBase.h

Go to the documentation of this file.
00001 /*
00002  * $Id: arrayBase.h,v 1.4 2003/07/06 07:41:34 jmk Exp $
00003  */
00004 ///////////////////////////////////////////////////////////////////////////
00005 //              _____________  ______________________    __   __  _____
00006 //             /  ________  |  |   ___   ________   /   |  \ /  \   |
00007 //            |  |       |  |_ |  |_ |  |       /  /    \__  |      |
00008 //            |  |  ___  |  || |  || |  |      /  /        | |      |
00009 //            |  | |   \ |  || |  || |  |     /  /      \__/ \__/ __|__
00010 //            |  | |_@  ||  || |  || |  |    /  /          Institute
00011 //            |  |___/  ||  ||_|  || |  |   /  /_____________________
00012 //             \_______/  \______/ | |__|  /___________________________
00013 //                        |  |__|  |
00014 //                         \______/
00015 //                    University of Utah       
00016 //                           2002
00017 ///////////////////////////////////////////////////////////////////////////
00018 ////////////////////////////////////////////////////////////////////////
00019 // 9/8/02       Joe M. Knis         Scientific Computing and Imaging Institute
00020 //                                                      School of Computing
00021 //                                                      University of Utah
00022 //
00023 //         arrayBase.h This is a base class for all arrays in gutz
00024 //         - it knows its 
00025 //                * dimension
00026 //                * size of each axis
00027 //                * the data pointer
00028 //                * total size of the array
00029 ////////////////////////////////////////////////////////////////////////
00030 
00031 
00032 #ifndef ARRAY_BASE_h
00033 #define ARRAY_BASE_h
00034 
00035 #include <assert.h>
00036 #include "../mathGutz/mm.h"
00037 
00038 #ifdef USING_MATHGUTZ
00039         #include <mathGutz.h>
00040 #endif
00041 
00042 namespace gutz
00043 {
00044 
00045 #define MAX_ARRAY_DIM_GUTZ 5
00046 
00047 //////////////////////////////
00048 // arrayBase
00049 //////////////////////////////
00050 template <class T>
00051 class arrayBase
00052 {
00053 public:
00054         arrayBase();
00055         //assignment constructors implicitly set the dimension
00056         arrayBase(int d0, T* a);
00057         arrayBase(int d0, int d1, T* a);
00058         arrayBase(int d0, int d1, int d2, T* a);
00059         arrayBase(int d0, int d1, int d2, int d3, T* a);
00060         arrayBase(int d0, int d1, int d2, int d3, int d4, T* a);
00061         //This assignment constructor explicitly sets the dimension
00062         arrayBase(int dim, int* aSize, T* a);
00063 
00064         //copy constructor, creates an identical array
00065         arrayBase( const arrayBase<T> &a);
00066 
00067         // 10/10/02 Added by Aaron Lefohn
00068         // - I think that operator= should have the same 
00069         //   functionality as the copy ctor. If other, non-trad
00070         //   assignments are required, they should exist via
00071         //   a member function such as "transfer" or "wrap"
00072         // (OLD comment: "assignment operator, assumes data is WRAPPED by class,
00073         //                                only sets the data pointer and total size, YOU specify the 
00074         //                                dimension and axis sizes when you construct the class")
00075         arrayBase<T>& operator=( const arrayBase<T>& a );
00076 
00077     // Return the element at data(i,j,k,m,n)
00078         inline T&                                       operator() (int i, int j=0, int k=0, int m=0, int n=0);
00079         inline const T&                         operator() (int i, int j=0, int k=0, int m=0, int n=0) const;
00080 
00081         // Return the dimension of the array
00082         inline int    dim() const {return mDim;}
00083         // Return the size of an axis
00084         inline int    dim(const int axis) const {return mAxisDim[axis];}
00085 
00086         // Total elements in array
00087         inline int    size() const {return mSize;}
00088 
00089         // Is the array empty
00090         inline int    empty() const {return mData==NULL || mSize==0;}
00091 
00092         // Get the data
00093         inline T*               data()           { return mData; }
00094         inline const T* data() const { return mData; }
00095 
00096         // Should the data be deleted with 'delete' or 'malloc'?
00097         // - NOTE: Data only deleted by 'arrayOwnN<T>' classes, not by arrayWrapN<T>
00098         inline bool             killWithDelete() const {return mKillWithDelete;}
00099 
00100         // Reshape the axes sizes, does not change dimension of array, does not reallocate data
00101         inline void     reshape( int d0, int d1 = 0, int d2 = 0, int d3 = 0, int d4 = 0 );
00102 
00103 
00104 protected:
00105         T*   mData;                              ///< data pointer
00106 
00107         int  mAxisDim[MAX_ARRAY_DIM_GUTZ];       ///< # of elements allong each axis
00108         int  mAxisStride[MAX_ARRAY_DIM_GUTZ];    ///< # of elements to jump for the next entry
00109         int  mSize;                              ///< total # of elements in array
00110         int  mDim;                               ///< # of axes in array
00111         bool mKillWithDelete;                                    ///< Kill data with delete or free?
00112 
00113         inline void set( int dim, int* aSize, T* a);     ///< # of axies, # of elements per axis, data pointer
00114         //inline int  address(int i, int j, int k, int m, int n); ///< address of array element 
00115         inline const int  address(int i, int j, int k, int m, int n) const; ///< address of array element
00116         
00117         // ***************************************
00118         // ****   arrayOwn routines
00119         // ***************************************
00120         // Init memory from a single value
00121         // Preconditions: 1) mData MUST already be [] deleted if necessary
00122         //                                2) mSize MUST be set
00123         inline void initValOwn(T val);
00124         inline void initDataOwn(const T* data); // Calls allocCopyOwn and copyDataOwn
00125         inline void copyDataOwn(const T* data); // Copies data: does NOT allocate memory
00126         inline void allocDataOwn();                             // Allocates data, does NOT copy memory
00127         inline void killData(); // Called by arrayOwnN<T> destructors
00128 };
00129 
00130 //////////////////////////////
00131 // Implementation
00132 //////////////////////////////
00133 
00134 /// Default constructor
00135 template<class T>
00136 arrayBase<T>::arrayBase()
00137 :mData(0),mSize(0),mDim(0),mKillWithDelete(true)
00138 {
00139 }
00140 
00141 template<class T>
00142 arrayBase<T>::arrayBase(int d0, T* a)
00143 {
00144         int sizes[1];
00145         sizes[0] = d0;
00146         set(1, sizes, a);
00147 }
00148 
00149 template<class T>
00150 arrayBase<T>::arrayBase(int d0, int d1, T* a)
00151 {
00152         int sizes[2];
00153         sizes[0] = d0;
00154         sizes[1] = d1;
00155         set(2, sizes, a);
00156 }
00157 
00158 template<class T>
00159 arrayBase<T>::arrayBase(int d0, int d1, int d2, T* a)
00160 {
00161         int sizes[3];
00162         sizes[0] = d0;
00163         sizes[1] = d1;
00164         sizes[2] = d2;
00165         set(3, sizes, a);
00166 }
00167 
00168 template<class T>
00169 arrayBase<T>::arrayBase(int d0, int d1, int d2, int d3, T* a)
00170 {
00171         int sizes[4];
00172         sizes[0] = d0;
00173         sizes[1] = d1;
00174         sizes[2] = d2;
00175         sizes[3] = d3;
00176         set(4, sizes, a);
00177 }
00178 
00179 template<class T>
00180 arrayBase<T>::arrayBase(int d0, int d1, int d2, int d3, int d4, T* a)
00181 {
00182         int sizes[5];
00183         sizes[0] = d0;
00184         sizes[1] = d1;
00185         sizes[2] = d2;
00186         sizes[3] = d3;
00187         sizes[4] = d3;
00188         set(5, sizes, a);
00189 }
00190 
00191 template<class T>
00192 arrayBase<T>::arrayBase(int dim, int *aSize, T* a)
00193 {
00194         set(dim, aSize, a);
00195 }
00196 
00197 //copy constructor, creates an identical array
00198 // SHALLOW COPY!
00199 template<class T>
00200 arrayBase<T>::arrayBase( const arrayBase<T> &a)
00201 {
00202         assert( MAX_ARRAY_DIM_GUTZ == 5 );
00203         int sizes[MAX_ARRAY_DIM_GUTZ];
00204         sizes[0] = a.mAxisDim[0];
00205         sizes[1] = a.mAxisDim[1];
00206         sizes[2] = a.mAxisDim[2];
00207         sizes[3] = a.mAxisDim[3];
00208         sizes[4] = a.mAxisDim[4];
00209 
00210         set(a.mDim, sizes, a.mData);
00211 
00212 /*      mDim  = a.mDim;
00213         mSize = a.mSize;
00214         mData = a.mData;
00215 
00216         mAxisDim[0] = a.mAxisDim[0];
00217         mAxisDim[1] = a.mAxisDim[1];
00218         mAxisDim[2] = a.mAxisDim[2];
00219         mAxisDim[3] = a.mAxisDim[3];
00220         mAxisDim[4] = a.mAxisDim[4];
00221 
00222         mAxisStride[0] = a.mAxisStride[0];
00223         mAxisStride[1] = a.mAxisStride[1];
00224         mAxisStride[2] = a.mAxisStride[2];
00225         mAxisStride[3] = a.mAxisStride[3];
00226         mAxisStride[4] = a.mAxisStride[4];
00227 */
00228 }
00229 
00230 //assignment operator
00231 // SHALLOW COPY
00232 // 10/10/02 Added by Aaron Lefohn
00233 // - I think that operator= should have the same 
00234 //   functionality as the copy ctor. If other, non-trad
00235 //   assignments are required, they should exist via
00236 //   a member function such as "transfer" or "wrap"
00237 template<class T>
00238 arrayBase<T>& arrayBase<T>::operator=( const arrayBase<T>& a )
00239 {
00240         if( this != &a ) {
00241                 assert( MAX_ARRAY_DIM_GUTZ == 5 );
00242                 int sizes[MAX_ARRAY_DIM_GUTZ];
00243                 sizes[0] = a.mAxisDim[0];
00244                 sizes[1] = a.mAxisDim[1];
00245                 sizes[2] = a.mAxisDim[2];
00246                 sizes[3] = a.mAxisDim[3];
00247                 sizes[4] = a.mAxisDim[4];
00248 
00249                 set(a.mDim, sizes, a.mData);
00250 
00251         /*      mDim  = a.mDim;
00252                 mSize = a.size();
00253                 mData = (T*)a.data();
00254 
00255                 mAxisDim[0] = a.mAxisDim[0];
00256                 mAxisDim[1] = a.mAxisDim[1];
00257                 mAxisDim[2] = a.mAxisDim[2];
00258                 mAxisDim[3] = a.mAxisDim[3];
00259                 mAxisDim[4] = a.mAxisDim[4];
00260 
00261                 mAxisStride[0] = a.mAxisStride[0];
00262                 mAxisStride[1] = a.mAxisStride[1];
00263                 mAxisStride[2] = a.mAxisStride[2];
00264                 mAxisStride[3] = a.mAxisStride[3];
00265                 mAxisStride[4] = a.mAxisStride[4];
00266         */
00267         }
00268         return *this;
00269 }
00270 
00271 // Return the element at data(i,j,k,m)
00272 template<class T>
00273 T& arrayBase<T>::operator() (int i, int j, int k, int m, int n)
00274 {
00275         return mData[address(i,j,k,m,n)];
00276 }
00277 
00278 template<class T>
00279 const T& arrayBase<T>::operator() (int i, int j, int k, int m, int n) const
00280 {
00281         return mData[address(i,j,k,m,n)];
00282 }
00283 
00284 template<class T>
00285 const int arrayBase<T>::address(int i, int j, int k, int m, int n) const///< address of array element   
00286 {
00287         assert(mSize < (i*mAxisStride[0] + j*mAxisStride[1] + k*mAxisStride[2] +
00288                                         m*mAxisStride[3] + n*mAxisStride[4]));
00289         return i*mAxisStride[0] + j*mAxisStride[1] + k*mAxisStride[2] + m*mAxisStride[3] + n*mAxisStride[4];
00290 }
00291 
00292 template<class T>
00293 void arrayBase<T>::set( int dim, int* aSize, T* a)
00294 {
00295         assert(dim >= 0 );
00296         assert(dim <= MAX_ARRAY_DIM_GUTZ);
00297         
00298         //Zero out everything
00299         for(int s=0; s<MAX_ARRAY_DIM_GUTZ; ++s)
00300         {
00301                 mAxisStride[s] = 0;
00302                 mAxisDim[s] = 0;
00303         }
00304 
00305         //Set the member variables
00306         mDim = dim;
00307         int size = dim > 0 ? 1 : 0;  
00308         for(int i=0; i<dim; ++i)
00309         {
00310                 //Axis size & total size
00311                 mAxisDim[i] = aSize[i];
00312                 //if(i==0) size = aSize[i];
00313                 //else 
00314                 size *= aSize[i];
00315                 
00316                 //Strides
00317                 mAxisStride[i] = 1;
00318                 for(int j=i+1; j<dim; ++j)
00319                 {
00320                         mAxisStride[i] *= aSize[j];
00321                         assert(aSize[j] > 0);
00322                 }
00323         }
00324         //Set the total size and array pointer
00325         mSize = size;
00326         mData = a;
00327         mKillWithDelete = true;
00328 }
00329 
00330 template<class T>
00331 void arrayBase<T>::reshape( int d0, int d1, int d2, int d3, int d4)
00332 {
00333         //Set the new dimensions
00334         mAxisDim[0] = d0;
00335         mAxisDim[1] = d1;
00336         mAxisDim[2] = d2;
00337         mAxisDim[3] = d3;
00338         mAxisDim[4] = d4;
00339 
00340         //Set the strides
00341         for(int i=0; i<mDim; ++i)
00342         {               
00343                 mAxisStride[i] = 1;
00344                 for(int j=i+1; j<mDim; ++j)
00345                 {
00346                         mAxisStride[i] *= mAxisDim[j];
00347                 }
00348         }
00349 }
00350 
00351 // ***************************************
00352 // ****   arrayOwn routines
00353 // ***************************************
00354 // Init memory from a single value
00355 // Preconditions: 1) mData MUST already be [] deleted if necessary
00356 //                                2) mSize MUST be set
00357 template <class T>
00358 void arrayBase<T>::initValOwn(T val)
00359 {
00360         if( mSize > 0 ) {
00361                 mData = new T[mSize];
00362                 assert(mData);
00363                 for (int i=0; i<mSize; i++) { mData[i] = val; } 
00364         }
00365 }
00366 
00367 // Init memory from an array
00368 // Init memory from a single value
00369 // Preconditions: 1) mData MUST already be [] deleted if necessary
00370 //                                2) mSize MUST be set
00371 template <class T>
00372 void arrayBase<T>::initDataOwn(const T* data)
00373 {       
00374         // Do DEEP copy of 'data'
00375         /*if( mSize > 0 ) {
00376             mData = new T[mSize];
00377                 assert(mData);
00378                 for (int i=0; i<mSize; i++) { mData[i] = data[i]; }     
00379         }*/
00380         allocDataOwn();
00381         copyDataOwn(data);
00382 }
00383 
00384 // ****************************
00385 //TODO: Remove THIS!!!!
00386 //#include <iostream>
00387 //using namespace std;
00388 // ****************************
00389 
00390 template <class T>
00391 void arrayBase<T>::allocDataOwn()
00392 {
00393         //cerr << "arrayBase<T>::allocDataOwn() Called\n";
00394         if( mSize > 0 ) {
00395                 mData = new T[mSize];
00396                 assert(mData);
00397         }
00398 }
00399 
00400 template <class T>
00401 void arrayBase<T>::copyDataOwn(const T* data)
00402 {
00403         if( mSize > 0 && mData) {
00404                 for (int i=0; i<mSize; i++) { mData[i] = data[i]; }     
00405         }
00406 }
00407 
00408 // Delete old mem
00409 template <class T>
00410 void arrayBase<T>::killData()
00411 {
00412         //cerr << "arrayBase<T>::killData() Called\n";
00413         if( mData ) {                                           
00414                 if( mKillWithDelete ) {
00415                         delete [] mData;
00416                 }
00417                 else {
00418                         free(mData);
00419                 }
00420                 mData = NULL;
00421         }
00422 }
00423 
00424 
00425 ////////////////////////////////////
00426 // Typedefs
00427 ////////////////////////////////////
00428 
00429 typedef arrayBase<char>         arraybc;
00430 typedef arrayBase<uchar>        arraybuc;
00431 typedef arrayBase<char>         arraybb;
00432 typedef arrayBase<uchar>        arraybub;
00433 typedef arrayBase<short>        arraybs;
00434 typedef arrayBase<ushort>       arraybus;
00435 typedef arrayBase<int>          arraybi;
00436 typedef arrayBase<uint>         arraybui;
00437 typedef arrayBase<long>         arraybl;
00438 typedef arrayBase<ulong>        arraybul;
00439 typedef arrayBase<llong>        arraybll;
00440 typedef arrayBase<ullong>       arraybull;
00441 typedef arrayBase<float>        arraybf;
00442 typedef arrayBase<double>       arraybd;
00443 
00444 #ifdef USING_MATHGUTZ
00445         typedef arrayBase<vec2ub> arraybv2ub;
00446         typedef arrayBase<vec2i>  arraybv2i;
00447         typedef arrayBase<vec2ui> arraybv2ui;
00448         typedef arrayBase<vec2f>  arraybv2f;
00449 
00450         typedef arrayBase<vec3ub> arraybv3ub;
00451         typedef arrayBase<vec3i>  arraybv3i;
00452         typedef arrayBase<vec3ui> arraybv3ui;
00453         typedef arrayBase<vec3f>  arraybv3f;
00454 
00455         typedef arrayBase<vec4ub> arraybv4ub;
00456         typedef arrayBase<vec4i>  arraybv4i;
00457         typedef arrayBase<vec4ui> arraybv4ui;
00458         typedef arrayBase<vec4f>  arraybv4f;
00459 
00460         typedef arrayBase<mat2ub> arraybm2ub;
00461         typedef arrayBase<mat2i>  arraybm2i;
00462         typedef arrayBase<mat2ui> arraybm2ui;
00463         typedef arrayBase<mat2f>  arraybm2f;
00464 
00465         typedef arrayBase<mat3ub> arraybm3ub;
00466         typedef arrayBase<mat3i>  arraybm3i;
00467         typedef arrayBase<mat3ui> arraybm3ui;
00468         typedef arrayBase<mat3f>  arraybm3f;
00469 
00470         typedef arrayBase<mat4ub> arraybm4ub;
00471         typedef arrayBase<mat4i>  arraybm4i;
00472         typedef arrayBase<mat4ui> arraybm4ui;
00473         typedef arrayBase<mat4f>  arraybm4f;
00474 #endif
00475 
00476 }//end namespace gutz
00477 #endif
00478 

Send questions, comments, and bug reports to:
jmk