00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef PLANCK_ARR_H
00035 #define PLANCK_ARR_H
00036
00037 #include "cxxutils.h"
00038 #include <algorithm>
00039
00040
00041
00042
00043
00044
00045 template <typename T, unsigned int sz> class fix_arr
00046 {
00047 private:
00048 T d[sz];
00049
00050 public:
00051
00052 long size() const { return sz; }
00053
00054
00055 template<typename T2> T &operator[] (T2 n) {return d[n];}
00056
00057 template<typename T2> const T &operator[] (T2 n) const {return d[n];}
00058 };
00059
00060
00061
00062 template <typename T> class arr
00063 {
00064 private:
00065 long s;
00066 T *d;
00067 bool own;
00068
00069 #if defined(PLANCK_CHECKS)
00070 void check_range(long n) const
00071 {
00072 if ((n<0) || (n>=s)) throw Message_error
00073 ("arr: index "+dataToString(n)+" is out of range. Max index is "
00074 +dataToString(s-1));
00075 }
00076 #endif
00077
00078 void reset()
00079 { s=0; d=0; own=true; }
00080
00081 public:
00082
00083 arr() : s(0), d(0), own(true) {}
00084
00085 arr(long sz) : s(sz), d (s>0 ? new T[s] : 0), own(true) {}
00086
00087
00088 arr(long sz, const T &inival) : s(sz), d (s>0 ? new T[s] : 0), own(true)
00089 { fill(inival); }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 arr (T *ptr, long sz): s(sz), d(ptr), own(false) {}
00102
00103
00104 arr (const arr &orig): s(orig.s), d (s>0 ? new T[s] : 0), own(true)
00105 { for (long m=0; m<s; ++m) d[m] = orig.d[m]; }
00106
00107 ~arr() { if (own) delete[] d; }
00108
00109
00110 long size() const { return s; }
00111
00112
00113
00114
00115 void alloc (long sz)
00116 {
00117 if (sz==s) return;
00118 if (own) delete[] d;
00119 s = sz;
00120 d = s>0 ? new T[sz] : 0;
00121 own = true;
00122 }
00123
00124
00125 void dealloc () {if (own) delete[] d; reset();}
00126
00127
00128 void fill (const T &val)
00129 { for (long m=0; m<s; ++m) d[m]=val; }
00130
00131
00132 arr &operator= (const arr &orig)
00133 {
00134 if (this==&orig) return *this;
00135 alloc (orig.s);
00136 for (long m=0; m<s; ++m) d[m] = orig.d[m];
00137 return *this;
00138 }
00139
00140 #if defined (PLANCK_CHECKS)
00141 template<typename T2> T &operator[] (T2 n) {check_range(n); return d[n];}
00142 template<typename T2> const T &operator[] (T2 n) const
00143 {check_range(n); return d[n];}
00144 #else
00145
00146 template<typename T2> T &operator[] (T2 n) {return d[n];}
00147
00148 template<typename T2> const T &operator[] (T2 n) const {return d[n];}
00149 #endif
00150
00151 T *begin() { return d; }
00152 T *end() { return d+s; }
00153
00154
00155 void sort()
00156 { std::sort (d,d+s); }
00157
00158
00159
00160 void minmax (T &minv, T &maxv) const
00161 {
00162 planck_assert(s>0,"trying to find min and max of a zero-sized array");
00163 minv=maxv=d[0];
00164 for (int m=1; m<s; ++m)
00165 {
00166 if (d[m]<minv) minv=d[m];
00167 else if (d[m]>maxv) maxv=d[m];
00168 }
00169 }
00170
00171
00172
00173 void transfer (arr &other)
00174 { if (own) delete[] d; d=other.d; s=other.s; own=other.own; other.reset(); }
00175
00176 void swap (arr &other)
00177 { std::swap(d,other.d); std::swap(s,other.s); std::swap(own,other.own);}
00178 };
00179
00180
00181
00182
00183 template <typename T> class arr2
00184 {
00185 private:
00186 long s1, s2;
00187 arr<T> d;
00188
00189 #if defined (PLANCK_CHECKS)
00190 void check_range(long n) const
00191 {
00192 if ((n<0) || (n>=s1)) throw Message_error
00193 ("arr2: index "+dataToString(n)+" is out of range. Max index is "
00194 +dataToString(s1-1));
00195 }
00196 #endif
00197
00198 public:
00199
00200 arr2() : s1(0), s2(0) {}
00201
00202 arr2(long sz1, long sz2)
00203 : s1(sz1), s2(sz2), d(s1*s2) {}
00204
00205 arr2(const arr2 &orig)
00206 : s1(orig.s1), s2(orig.s2), d(orig.d) {}
00207
00208 ~arr2() {}
00209
00210
00211 long size1() const { return s1; }
00212
00213 long size2() const { return s2; }
00214
00215 long size () const { return s1*s2; }
00216
00217
00218
00219
00220
00221 void alloc (long sz1, long sz2)
00222 {
00223 if (sz1*sz2 != d.size())
00224 d.alloc(sz1*sz2);
00225 s1=sz1; s2=sz2;
00226 }
00227
00228
00229
00230
00231 void fast_alloc (long sz1, long sz2)
00232 {
00233 if (sz1*sz2<=d.size())
00234 { s1=sz1; s2=sz2; }
00235 else
00236 alloc(sz1,sz2);
00237 }
00238
00239 void dealloc () {d.dealloc(); s1=0; s2=0;}
00240
00241
00242 void fill (const T &val)
00243 { d.fill(val); }
00244
00245
00246 arr2 &operator= (const arr2 &orig)
00247 {
00248 if (this==&orig) return *this;
00249 alloc (orig.s1, orig.s2);
00250 d = orig.d;
00251 return *this;
00252 }
00253
00254 #if defined (PLANCK_CHECKS)
00255 template<typename T2> T *operator[] (T2 n)
00256 {check_range(n);return &d[n*s2];}
00257 template<typename T2> const T *operator[] (T2 n) const
00258 {check_range(n);return &d[n*s2];}
00259 #else
00260
00261 template<typename T2> T *operator[] (T2 n) {return &d[n*s2];}
00262
00263 template<typename T2> const T *operator[] (T2 n) const {return &d[n*s2];}
00264 #endif
00265
00266
00267
00268 void minmax (T &minv, T &maxv) const
00269 {
00270 planck_assert(s1*s2>0,
00271 "trying to find min and max of a zero-sized array");
00272 minv=maxv=d[0];
00273 for (int m=1; m<s1*s2; ++m)
00274 {
00275 if (d[m]<minv) minv=d[m];
00276 if (d[m]>maxv) maxv=d[m];
00277 }
00278 }
00279
00280
00281 void swap (arr2 &other)
00282 {
00283 d.swap(other.d);
00284 std::swap(s1,other.s1);
00285 std::swap(s2,other.s2);
00286 }
00287 };
00288
00289
00290
00291 template <typename T> class arr2b
00292 {
00293 private:
00294 long s1, s2;
00295 arr<T> d;
00296 arr<T *> d1;
00297
00298 #if defined (PLANCK_CHECKS)
00299 void check_range(long n) const
00300 {
00301 if ((n<0) || (n>=s1)) throw Message_error
00302 ("arr: index "+dataToString(n)+" is out of range. Max index is "
00303 +dataToString(s1-1));
00304 }
00305 #endif
00306
00307 void fill_d1()
00308 { for (long m=0; m<s1; ++m) d1[m] = &d[m*s2]; }
00309
00310 public:
00311
00312 arr2b() : s1(0), s2(0), d(0), d1(0) {}
00313
00314 arr2b(long sz1, long sz2)
00315 : s1(sz1), s2(sz2), d(s1*s2), d1(s1)
00316 { fill_d1(); }
00317
00318 arr2b(const arr2b &orig)
00319 : s1(orig.s1), s2(orig.s2), d(orig.d), d1(s1)
00320 { fill_d1(); }
00321
00322 ~arr2b() {}
00323
00324
00325 long size1() const { return s1; }
00326
00327 long size2() const { return s2; }
00328
00329 long size () const { return s1*s2; }
00330
00331
00332
00333 void alloc (long sz1, long sz2)
00334 {
00335 if ((s1==sz1) && (s2==sz2)) return;
00336 s1=sz1; s2=sz2;
00337 d.alloc(s1*s2);
00338 d1.alloc(s1);
00339 fill_d1();
00340 }
00341
00342 void dealloc () {d.dealloc(); d1.dealloc(); s1=0; s2=0;}
00343
00344
00345 void fill (const T &val)
00346 { d.fill(val); }
00347
00348
00349 arr2b &operator= (const arr2b &orig)
00350 {
00351 if (this==&orig) return *this;
00352 alloc (orig.s1, orig.s2);
00353 for (long m=0; m<s1*s2; ++m) d[m] = orig.d[m];
00354 return *this;
00355 }
00356
00357 #if defined (PLANCK_CHECKS)
00358 template<typename T2> T *operator[] (T2 n) {check_range(n); return d1[n];}
00359 template<typename T2> const T *operator[] (T2 n) const
00360 {check_range(n); return d1[n];}
00361 #else
00362
00363 template<typename T2> T *operator[] (T2 n) {return d1[n];}
00364
00365 template<typename T2> const T *operator[] (T2 n) const {return d1[n];}
00366 #endif
00367
00368 T **p0() {return &d1[0];}
00369 };
00370
00371
00372
00373
00374
00375 template <typename T> class arr3
00376 {
00377 private:
00378 long s1, s2, s3, s2s3;
00379 arr<T> d;
00380
00381 public:
00382
00383 arr3() : s1(0), s2(0), s3(0), s2s3(0), d(0) {}
00384
00385 arr3(long sz1, long sz2, long sz3)
00386 : s1(sz1), s2(sz2), s3(sz3), s2s3(s2*s3), d(s1*s2*s3) {}
00387
00388 arr3(const arr3 &orig)
00389 : s1(orig.s1), s2(orig.s2), s3(orig.s3), s2s3(orig.s2s3), d(orig.d) {}
00390
00391 ~arr3() {}
00392
00393
00394 long size1() const { return s1; }
00395
00396 long size2() const { return s2; }
00397
00398 long size3() const { return s3; }
00399
00400 long size () const { return s1*s2*s3; }
00401
00402
00403
00404 void alloc (long sz1, long sz2, long sz3)
00405 {
00406 d.alloc(sz1*sz2*sz3);
00407 s1=sz1; s2=sz2; s3=sz3; s2s3=s2*s3;
00408 }
00409
00410 void dealloc () {d.dealloc(); s1=0; s2=0; s3=0; s2s3=0;}
00411
00412
00413 void fill (const T &val)
00414 { d.fill(val); }
00415
00416
00417 arr3 &operator= (const arr3 &orig)
00418 {
00419 if (this==&orig) return *this;
00420 alloc (orig.s1, orig.s2, orig.s3);
00421 d = orig.d;
00422 return *this;
00423 }
00424
00425
00426
00427 template<typename T2> T &operator() (T2 n1, T2 n2, T2 n3)
00428 {return d[n1*s2s3 + n2*s3 + n3];}
00429
00430
00431 template<typename T2> const T &operator() (T2 n1, T2 n2, T2 n3) const
00432 {return d[n1*s2s3 + n2*s3 + n3];}
00433
00434
00435 void swap (arr3 &other)
00436 {
00437 d.swap(other.d);
00438 std::swap(s1,other.s1);
00439 std::swap(s2,other.s2);
00440 std::swap(s3,other.s3);
00441 std::swap(s2s3,other.s2s3);
00442 }
00443 };
00444
00445
00446
00447 #endif