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;
00026 uint nc, c[IMAX];
00027 uint imax;
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
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
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
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 };