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 #ifndef PLANCK_ARR_H
00033 #define PLANCK_ARR_H
00034
00035 #include <algorithm>
00036 #include <vector>
00037 #include <cstdlib>
00038 #include "alloc_utils.h"
00039 #include "datatypes.h"
00040 #include "math_utils.h"
00041
00042
00043
00044
00045
00046 template <typename T> class arr_ref
00047 {
00048 protected:
00049 tsize s;
00050 T *d;
00051
00052 public:
00053
00054 arr_ref(T *d_, tsize s_) : s(s_),d(d_) {}
00055
00056
00057 tsize size() const { return s; }
00058
00059
00060 void fill (const T &val)
00061 { for (tsize m=0; m<s; ++m) d[m]=val; }
00062
00063
00064 template<typename T2> T &operator[] (T2 n) {return d[n];}
00065
00066 template<typename T2> const T &operator[] (T2 n) const {return d[n];}
00067
00068
00069
00070 T *begin() { return d; }
00071
00072
00073 T *end() { return d+s; }
00074
00075
00076 const T *begin() const { return d; }
00077
00078
00079 const T *end() const { return d+s; }
00080
00081
00082 template<typename T2> void copyToPtr (T *ptr) const
00083 { for (tsize m=0; m<s; ++m) ptr[m]=d[m]; }
00084
00085
00086 void sort()
00087 { std::sort (d,d+s); }
00088
00089
00090
00091 template<typename Comp> void sort(Comp comp)
00092 { std::sort (d,d+s,comp); }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 void interpol_helper (const T &val, tsize &idx, double &frac) const
00103 { ::interpol_helper (d, d+s, val, idx, frac); }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 template<typename Comp> void interpol_helper (const T &val, Comp comp,
00114 tsize &idx, double &frac) const
00115 { ::interpol_helper (d, d+s, val, comp, idx, frac); }
00116
00117
00118
00119 void minmax (T &minv, T &maxv) const
00120 {
00121 planck_assert(s>0,"trying to find min and max of a zero-sized array");
00122 minv=maxv=d[0];
00123 for (tsize m=1; m<s; ++m)
00124 {
00125 if (d[m]<minv) minv=d[m];
00126 else if (d[m]>maxv) maxv=d[m];
00127 }
00128 }
00129
00130
00131 bool contains (const T &val) const
00132 {
00133 for (tsize m=0; m<s; ++m)
00134 if (d[m]==val) return true;
00135 return false;
00136 }
00137
00138
00139
00140 tsize find (const T &val) const
00141 {
00142 for (tsize m=0; m<s; ++m)
00143 if (d[m]==val) return m;
00144 planck_fail ("entry not found in array");
00145 }
00146
00147
00148
00149 bool contentsEqual(const arr_ref &other) const
00150 {
00151 if (s!=other.s) return false;
00152 for (tsize i=0; i<s; ++i)
00153 if (d[i]!=other.d[i]) return false;
00154 return true;
00155 }
00156 };
00157
00158
00159
00160 template <typename T, tsize sz> class fix_arr
00161 {
00162 private:
00163 T d[sz];
00164
00165 public:
00166
00167 tsize size() const { return sz; }
00168
00169
00170 template<typename T2> T &operator[] (T2 n) {return d[n];}
00171
00172 template<typename T2> const T &operator[] (T2 n) const {return d[n];}
00173 };
00174
00175
00176
00177 template <typename T, typename storageManager> class arrT: public arr_ref<T>
00178 {
00179 private:
00180 storageManager stm;
00181 bool own;
00182
00183 void reset()
00184 { this->d=0; this->s=0; own=true; }
00185
00186 public:
00187
00188 arrT() : arr_ref<T>(0,0), own(true) {}
00189
00190 arrT(tsize sz) : arr_ref<T>(stm.alloc(sz),sz), own(true) {}
00191
00192
00193 arrT(tsize sz, const T &inival) : arr_ref<T>(stm.alloc(sz),sz), own(true)
00194 { this->fill(inival); }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 arrT (T *ptr, tsize sz): arr_ref<T>(ptr,sz), own(false) {}
00207
00208
00209 arrT (const arrT &orig): arr_ref<T>(stm.alloc(orig.s),orig.s), own(true)
00210 { for (tsize m=0; m<this->s; ++m) this->d[m] = orig.d[m]; }
00211
00212 ~arrT() { if (own) stm.dealloc(this->d); }
00213
00214
00215
00216
00217 void alloc (tsize sz)
00218 {
00219 if (sz==this->s) return;
00220 if (own) stm.dealloc(this->d);
00221 this->s = sz;
00222 this->d = stm.alloc(sz);
00223 own = true;
00224 }
00225
00226
00227
00228 void allocAndFill (tsize sz, const T &inival)
00229 { alloc(sz); this->fill(inival); }
00230
00231
00232 void dealloc() {if (own) stm.dealloc(this->d); reset();}
00233
00234
00235
00236
00237 void resize (tsize sz)
00238 {
00239 using namespace std;
00240 if (sz==this->s) return;
00241 T *tmp = stm.alloc(sz);
00242 for (tsize m=0; m<min(sz,this->s); ++m)
00243 tmp[m]=this->d[m];
00244 if (own) stm.dealloc(this->d);
00245 this->s = sz;
00246 this->d = tmp;
00247 own = true;
00248 }
00249
00250
00251 arrT &operator= (const arrT &orig)
00252 {
00253 if (this==&orig) return *this;
00254 alloc (orig.s);
00255 for (tsize m=0; m<this->s; ++m) this->d[m] = orig.d[m];
00256 return *this;
00257 }
00258
00259
00260 template<typename T2> void copyFrom (const std::vector<T2> &orig)
00261 {
00262 alloc (orig.size());
00263 for (tsize m=0; m<this->s; ++m) this->d[m] = orig[m];
00264 }
00265
00266 template<typename T2> void copyTo (std::vector<T2> &vec) const
00267 {
00268 vec.clear(); vec.reserve(this->s);
00269 for (tsize m=0; m<this->s; ++m) vec.push_back(this->d[m]);
00270 }
00271
00272
00273
00274 template<typename T2> void copyFromPtr (const T2 *ptr, tsize sz)
00275 {
00276 alloc(sz);
00277 for (tsize m=0; m<this->s; ++m) this->d[m]=ptr[m];
00278 }
00279
00280
00281
00282 void transfer (arrT &other)
00283 {
00284 if (own) stm.dealloc(this->d);
00285 this->d=other.d;
00286 this->s=other.s;
00287 own=other.own;
00288 other.reset();
00289 }
00290
00291 void swap (arrT &other)
00292 {
00293 std::swap(this->d,other.d);
00294 std::swap(this->s,other.s);
00295 std::swap(own,other.own);
00296 }
00297 };
00298
00299
00300 template <typename T>
00301 class arr: public arrT<T,normalAlloc__<T> >
00302 {
00303 public:
00304
00305 arr() : arrT<T,normalAlloc__<T> >() {}
00306
00307 arr(tsize sz) : arrT<T,normalAlloc__<T> >(sz) {}
00308
00309
00310 arr(tsize sz, const T &inival) : arrT<T,normalAlloc__<T> >(sz,inival) {}
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 arr (T *ptr, tsize sz): arrT<T,normalAlloc__<T> >(ptr,sz) {}
00323
00324
00325 arr (const arr &orig): arrT<T,normalAlloc__<T> >(orig) {}
00326 };
00327
00328
00329 template <typename T, int align>
00330 class arr_align: public arrT<T,alignAlloc__<T,align> >
00331 {
00332 public:
00333
00334 arr_align() : arrT<T,alignAlloc__<T,align> >() {}
00335
00336 arr_align(tsize sz) : arrT<T,alignAlloc__<T,align> >(sz) {}
00337
00338
00339 arr_align(tsize sz, const T &inival)
00340 : arrT<T,alignAlloc__<T,align> >(sz,inival) {}
00341 };
00342
00343
00344
00345
00346
00347
00348 template <typename T, typename storageManager> class arr2T
00349 {
00350 private:
00351 tsize s1, s2;
00352 arrT<T, storageManager> d;
00353
00354 public:
00355
00356 arr2T() : s1(0), s2(0) {}
00357
00358 arr2T(tsize sz1, tsize sz2)
00359 : s1(sz1), s2(sz2), d(s1*s2) {}
00360
00361
00362 arr2T(tsize sz1, tsize sz2, const T &inival)
00363 : s1(sz1), s2(sz2), d (s1*s2)
00364 { fill(inival); }
00365
00366 arr2T(const arr2T &orig)
00367 : s1(orig.s1), s2(orig.s2), d(orig.d) {}
00368
00369 ~arr2T() {}
00370
00371
00372 tsize size1() const { return s1; }
00373
00374 tsize size2() const { return s2; }
00375
00376 tsize size () const { return s1*s2; }
00377
00378
00379
00380
00381
00382 void alloc (tsize sz1, tsize sz2)
00383 {
00384 if (sz1*sz2 != d.size())
00385 d.alloc(sz1*sz2);
00386 s1=sz1; s2=sz2;
00387 }
00388
00389
00390
00391
00392 void allocAndFill (tsize sz1, tsize sz2, const T &inival)
00393 { alloc(sz1,sz2); fill(inival); }
00394
00395
00396
00397
00398 void fast_alloc (tsize sz1, tsize sz2)
00399 {
00400 if (sz1*sz2<=d.size())
00401 { s1=sz1; s2=sz2; }
00402 else
00403 alloc(sz1,sz2);
00404 }
00405
00406 void dealloc () {d.dealloc(); s1=0; s2=0;}
00407
00408
00409 void fill (const T &val)
00410 { for (tsize m=0; m<s1*s2; ++m) d[m]=val; }
00411
00412
00413 void scale (const T &val)
00414 { for (tsize m=0; m<s1*s2; ++m) d[m]*=val; }
00415
00416
00417 arr2T &operator= (const arr2T &orig)
00418 {
00419 if (this==&orig) return *this;
00420 alloc (orig.s1, orig.s2);
00421 d = orig.d;
00422 return *this;
00423 }
00424
00425
00426 template<typename T2> T *operator[] (T2 n) {return &d[n*s2];}
00427
00428 template<typename T2> const T *operator[] (T2 n) const {return &d[n*s2];}
00429
00430
00431 template<typename T2, typename T3> T &operator() (T2 n1, T3 n2)
00432 {return d[n1*s2 + n2];}
00433
00434
00435 template<typename T2, typename T3> const T &operator() (T2 n1, T3 n2) const
00436 {return d[n1*s2 + n2];}
00437
00438
00439
00440 void minmax (T &minv, T &maxv) const
00441 {
00442 planck_assert(s1*s2>0,
00443 "trying to find min and max of a zero-sized array");
00444 minv=maxv=d[0];
00445 for (tsize m=1; m<s1*s2; ++m)
00446 {
00447 if (d[m]<minv) minv=d[m];
00448 if (d[m]>maxv) maxv=d[m];
00449 }
00450 }
00451
00452
00453 void swap (arr2T &other)
00454 {
00455 d.swap(other.d);
00456 std::swap(s1,other.s1);
00457 std::swap(s2,other.s2);
00458 }
00459
00460
00461
00462 template<typename T2, typename T3> bool conformable
00463 (const arr2T<T2,T3> &other) const
00464 { return (other.size1()==s1) && (other.size2()==s2); }
00465 };
00466
00467
00468
00469
00470 template <typename T>
00471 class arr2: public arr2T<T,normalAlloc__<T> >
00472 {
00473 public:
00474
00475 arr2() : arr2T<T,normalAlloc__<T> > () {}
00476
00477 arr2(tsize sz1, tsize sz2) : arr2T<T,normalAlloc__<T> > (sz1,sz2) {}
00478
00479
00480 arr2(tsize sz1, tsize sz2, const T &inival)
00481 : arr2T<T,normalAlloc__<T> > (sz1,sz2,inival) {}
00482 };
00483
00484
00485
00486
00487
00488 template <typename T, int align>
00489 class arr2_align: public arr2T<T,alignAlloc__<T,align> >
00490 {
00491 public:
00492
00493 arr2_align() : arr2T<T,alignAlloc__<T,align> > () {}
00494
00495 arr2_align(tsize sz1, tsize sz2)
00496 : arr2T<T,alignAlloc__<T,align> > (sz1,sz2) {}
00497
00498
00499 arr2_align(tsize sz1, tsize sz2, const T &inival)
00500 : arr2T<T,alignAlloc__<T,align> > (sz1,sz2,inival) {}
00501 };
00502
00503
00504
00505 template <typename T> class arr2b
00506 {
00507 private:
00508 tsize s1, s2;
00509 arr<T> d;
00510 arr<T *> d1;
00511
00512 void fill_d1()
00513 { for (tsize m=0; m<s1; ++m) d1[m] = &d[m*s2]; }
00514
00515 public:
00516
00517 arr2b() : s1(0), s2(0), d(0), d1(0) {}
00518
00519 arr2b(tsize sz1, tsize sz2)
00520 : s1(sz1), s2(sz2), d(s1*s2), d1(s1)
00521 { fill_d1(); }
00522
00523 arr2b(const arr2b &orig)
00524 : s1(orig.s1), s2(orig.s2), d(orig.d), d1(s1)
00525 { fill_d1(); }
00526
00527 ~arr2b() {}
00528
00529
00530 tsize size1() const { return s1; }
00531
00532 tsize size2() const { return s2; }
00533
00534 tsize size () const { return s1*s2; }
00535
00536
00537
00538 void alloc (tsize sz1, tsize sz2)
00539 {
00540 if ((s1==sz1) && (s2==sz2)) return;
00541 s1=sz1; s2=sz2;
00542 d.alloc(s1*s2);
00543 d1.alloc(s1);
00544 fill_d1();
00545 }
00546
00547 void dealloc () {d.dealloc(); d1.dealloc(); s1=0; s2=0;}
00548
00549
00550 void fill (const T &val)
00551 { d.fill(val); }
00552
00553
00554 arr2b &operator= (const arr2b &orig)
00555 {
00556 if (this==&orig) return *this;
00557 alloc (orig.s1, orig.s2);
00558 for (tsize m=0; m<s1*s2; ++m) d[m] = orig.d[m];
00559 return *this;
00560 }
00561
00562
00563 template<typename T2> T *operator[] (T2 n) {return d1[n];}
00564
00565 template<typename T2> const T *operator[] (T2 n) const {return d1[n];}
00566
00567
00568 T **p0() {return &d1[0];}
00569 };
00570
00571
00572
00573
00574
00575 template <typename T> class arr3
00576 {
00577 private:
00578 tsize s1, s2, s3, s2s3;
00579 arr<T> d;
00580
00581 public:
00582
00583 arr3() : s1(0), s2(0), s3(0), s2s3(0), d(0) {}
00584
00585 arr3(tsize sz1, tsize sz2, tsize sz3)
00586 : s1(sz1), s2(sz2), s3(sz3), s2s3(s2*s3), d(s1*s2*s3) {}
00587
00588 arr3(const arr3 &orig)
00589 : s1(orig.s1), s2(orig.s2), s3(orig.s3), s2s3(orig.s2s3), d(orig.d) {}
00590
00591 ~arr3() {}
00592
00593
00594 tsize size1() const { return s1; }
00595
00596 tsize size2() const { return s2; }
00597
00598 tsize size3() const { return s3; }
00599
00600 tsize size () const { return s1*s2*s3; }
00601
00602
00603
00604 void alloc (tsize sz1, tsize sz2, tsize sz3)
00605 {
00606 d.alloc(sz1*sz2*sz3);
00607 s1=sz1; s2=sz2; s3=sz3; s2s3=s2*s3;
00608 }
00609
00610 void dealloc () {d.dealloc(); s1=0; s2=0; s3=0; s2s3=0;}
00611
00612
00613 void fill (const T &val)
00614 { d.fill(val); }
00615
00616
00617 arr3 &operator= (const arr3 &orig)
00618 {
00619 if (this==&orig) return *this;
00620 alloc (orig.s1, orig.s2, orig.s3);
00621 d = orig.d;
00622 return *this;
00623 }
00624
00625
00626
00627 template<typename T2, typename T3, typename T4> T &operator()
00628 (T2 n1, T3 n2, T4 n3)
00629 {return d[n1*s2s3 + n2*s3 + n3];}
00630
00631
00632 template<typename T2, typename T3, typename T4> const T &operator()
00633 (T2 n1, T3 n2, T4 n3) const
00634 {return d[n1*s2s3 + n2*s3 + n3];}
00635
00636
00637 void swap (arr3 &other)
00638 {
00639 d.swap(other.d);
00640 std::swap(s1,other.s1);
00641 std::swap(s2,other.s2);
00642 std::swap(s3,other.s3);
00643 std::swap(s2s3,other.s2s3);
00644 }
00645
00646
00647
00648 template<typename T2> bool conformable (const arr3<T2> &other) const
00649 { return (other.size1()==s1)&&(other.size2()==s2)&&(other.size3()==s3); }
00650 };
00651
00652
00653
00654 #endif