Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

mdp_array.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00020 template <class T, uint nc_>
00021 class mdp_array {
00022  private:
00023   enum {FREE, HARD} flag;
00024   enum {IMAX=5};
00025   T    *m;        // data 
00026   uint  nc, c[IMAX];
00027   uint imax;      // total n. of elements
00028  public:
00029 
00030   inline const int& ndim() const {
00031     return nc;
00032   }
00033 
00034   inline T *address() {
00035     return m;
00036   }  
00037 
00038   inline uint* size_address() {
00039     return c;
00040   }  
00041 
00042   inline T& operator[] (const uint i) {
00043 #if defined(CHECK_ALL)
00044     if(i>=size()) error("mdp_array::operator[]\nIndex out of bounds");
00045 #endif
00046     return m[i];
00047   }
00048 
00049   inline const T& operator[] (const uint i) const {
00050 #if defined(CHECK_ALL)
00051     if(i>=size()) error("mdp_array::operator[]\nIndex out of bounds");
00052 #endif
00053     return m[i];
00054   }
00055 
00056   inline uint length(const uint i) const {
00057     return size(i);
00058   }
00059 
00060   inline uint length() const {
00061     return imax;
00062   }
00063 
00064   inline uint size(uint i) const {
00065 #if defined(CHECK_ALL)
00066     if(i>=size()) error("mdp_array::size(...)\nIndex out of bounds");
00067 #endif
00068     return c[i];
00069   }
00070 
00071   inline uint size() const {
00072     return imax;
00073   }
00074 
00075   inline void dimension(const uint* p) {
00076     if(flag!=FREE) error("mdp_array::dimension(...)\nCannot redimension a HARD object");
00077     register uint i;
00078     for(imax=1, i=0; i<nc; i++) imax*=(c[i]=p[i]); 
00079     for(i=nc; i<IMAX; i++) c[i]=1; 
00080     if(m!=0) delete[] m;
00081     m=new T[imax];
00082   }
00083 
00084   inline void dimension(const uint c0_=1, const uint c1_=1, const uint c2_=1, const uint c3_=1, const uint c4_=1) {
00085     if(m!=0) delete[] m;
00086     c[0]=c0_; imax=c0_;
00087     c[1]=c1_; imax*=c1_; 
00088     c[2]=c2_; imax*=c2_;
00089     c[3]=c3_; imax*=c3_;
00090     c[4]=c4_; imax*=c4_;
00091     m=new T[imax];
00092   }
00093 
00094   inline mdp_array(const uint c0_=1, const uint c1_=1, const uint c2_=1, const uint c3_=1, const uint c4_=1) { 
00095     flag=FREE;
00096     nc=nc_;
00097     m=0;
00098     dimension(c0_,c1_,c2_,c3_,c4_);
00099   }
00100 
00101   inline mdp_array(const uint* p) {
00102     flag=FREE;
00103     nc=nc_;
00104     m=0;
00105     dimension(p);
00106   }
00107 
00108   inline mdp_array(const T *m0, 
00109                    const uint c0_=1, 
00110                    const uint c1_=1, 
00111                    const uint c2_=1, 
00112                    const uint c3_=1, 
00113                    const uint c4_=1) { 
00114     flag=HARD;
00115     nc=nc_;
00116     m=0;
00117     dimension(c0_, c1_, c2_, c3_, c4_);
00118   }
00119 
00120   inline mdp_array(const T *m0,
00121                    const uint* p) {
00122     flag=HARD;
00123     nc=nc_;
00124     m=m0;
00125     imax=c[0]=p[0];
00126     uint i;
00127     for(i=1; i<nc; i++) imax*=(c[i]=p[i]);
00128     for(i=nc; i<IMAX; i++) c[i]=1;
00129   }
00130 
00131   inline mdp_array(const mdp_array &a) {
00132     flag=FREE;
00133     uint i;
00134     m=0;
00135     nc=nc_;
00136     if(nc!=a.nc) error("mdp_array::mdp_array(...)\nIncompatible size()");
00137     if(imax!=a.imax) dimension(a.imax);
00138     for(i=0; i<IMAX; i++) c[i]=a.c[i];
00139     for(i=0; i<imax; i++) m[i]=a.m[i];
00140   }   
00141 
00142   virtual ~mdp_array() {
00143     nc=imax=0;
00144     if(flag!=HARD && m!=0) delete[] m;
00145   }
00146 
00147   inline void operator= (const mdp_array& a) {
00148     uint i;
00149     nc=a.nc;
00150     if(nc!=a.nc) error("mdp_array::operator=(...)\nIncompatible size()");
00151     if(imax!=a.imax) dimension(a.imax);
00152     for(i=0; i<IMAX; i++) c[i]=a.c[i];
00153     for(i=0; i<imax; i++) m[i]=a.m[i];
00154   }
00155 
00156   inline friend void prepare (const mdp_array &a) {
00157     // do nothing...
00158   }
00159 
00160   inline friend mdp_array operator+ (const mdp_array& a, const mdp_array& b) {
00161     mdp_array tmp(a.c);
00162     for(register uint i=0; i<a.imax; i++) tmp[i]=a[i]+b[i];
00163     return tmp;
00164   }
00165 
00166   inline friend mdp_array operator- (const mdp_array& a, const mdp_array& b) {
00167     mdp_array tmp(a.c);
00168     for(register uint i=0; i<a.imax; i++) tmp[i]=a[i]-b[i];
00169     return tmp;
00170   }
00171 
00172   template<class T2>
00173   inline friend mdp_array operator* (T2 x, const mdp_array& a) {
00174     mdp_array tmp(a.c);
00175     for(register uint i=0; i<a.imax; i++) tmp[i]=a[i]*x;
00176     return tmp;
00177   }
00178 
00179   // Implementation of generic unary operator
00180   inline friend mdp_array applytoall (const mdp_array& a, 
00181                                       T (*fptr)(T,void*), void *x=0) {
00182     mdp_array tmp(a.c);
00183     for(register uint i=0; i<a.imax; i++) 
00184       tmp[i]=(*fptr)(a[i],x);
00185     return tmp;
00186   }
00187 
00188   // implementation of generic binary operator
00189   inline friend mdp_array applytoall (const mdp_array& a, const mdp_array& b, 
00190                                        T (*fptr)(T,T,void*), void* x=0) {
00191     mdp_array tmp(a.c);
00192     for(register uint i=0; i<a.imax; i++) 
00193       tmp[i]=(*fptr)(a[i], b[i],x);
00194     return tmp;
00195   }
00196 
00197   inline T &operator() (const uint i0, 
00198                         const uint i1=0, 
00199                         const uint i2=0, 
00200                         const uint i3=0, 
00201                         const uint i4=0) {
00202 #if defined(CHECK_ALL)
00203     if ((i1!=0 && nc<2) ||
00204         (i2!=0 && nc<3) ||
00205         (i3!=0 && nc<4) ||
00206         (i4!=0 && nc<IMAX))
00207       error("mdp_array::operator()(...)\nIncompatible size()");
00208     if(i0>=c[0]) error("mdp_array::operator()\nIndex out of bounds");
00209     if(i1>=c[1]) error("mdp_array::operator()\nIndex out of bounds");
00210     if(i2>=c[2]) error("mdp_array::operator()\nIndex out of bounds");
00211     if(i3>=c[3]) error("mdp_array::operator()\nIndex out of bounds");
00212     if(i4>=c[4]) error("mdp_array::operator()\nIndex out of bounds");
00213 #endif 
00214     return m[(((i0*c[1]+i1)*c[2]+i2)*c[3]+i3)*c[4]+i4];
00215   }
00216 
00217   inline const T &operator() (const uint i0, 
00218                               const uint i1=0, 
00219                               const uint i2=0, 
00220                               const uint i3=0, 
00221                               const uint i4=0) const {
00222 #if defined(CHECK_ALL)
00223     if ((i1!=0 && nc<2) ||
00224         (i2!=0 && nc<3) ||
00225         (i3!=0 && nc<4) ||
00226         (i4!=0 && nc<IMAX))
00227       error("mdp_array::operator()(...)\nIncompatible size()");
00228     if(i0>=c[0]) error("mdp_array::operator()\nIndex out of bounds");
00229     if(i1>=c[1]) error("mdp_array::operator()\nIndex out of bounds");
00230     if(i2>=c[2]) error("mdp_array::operator()\nIndex out of bounds");
00231     if(i3>=c[3]) error("mdp_array::operator()\nIndex out of bounds");
00232     if(i4>=c[4]) error("mdp_array::operator()\nIndex out of bounds");
00233 #endif
00234     return m[(((i0*c[1]+i1)*c[2]+i2)*c[3]+i3)*c[4]+i4];
00235   }
00236 
00237   friend ostream& operator<< (ostream& os, const mdp_array& a) {
00238     uint i;
00239     os << "{";
00240 
00241     switch(a.ndim()) {      
00242     case 0:
00243       break;
00244     case 1:
00245       for(i=0; i<a.length(); i++) 
00246         if(i==0) os << " " << a[i];
00247         else  os << ", " << a[i];
00248       break;
00249     default:
00250       os << " Sorry. Option not implemented";
00251       break;
00252     }
00253     
00254     os << " }";
00255     return os;
00256   }
00257 };

Generated on Sun Feb 27 15:12:20 2005 by  doxygen 1.4.1