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