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 stm> class arrT: public arr_ref<T>
00178 {
00179 private:
00180 bool own;
00181
00182 void reset()
00183 { this->d=0; this->s=0; own=true; }
00184
00185 public:
00186
00187 arrT() : arr_ref<T>(0,0), own(true) {}
00188
00189 explicit arrT(tsize sz) : arr_ref<T>(stm::alloc(sz),sz), own(true) {}
00190
00191
00192 arrT(tsize sz, const T &inival) : arr_ref<T>(stm::alloc(sz),sz), own(true)
00193 { this->fill(inival); }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 arrT (T *ptr, tsize sz): arr_ref<T>(ptr,sz), own(false) {}
00206
00207
00208 arrT (const arrT &orig): arr_ref<T>(stm::alloc(orig.s),orig.s), own(true)
00209 { for (tsize m=0; m<this->s; ++m) this->d[m] = orig.d[m]; }
00210
00211 ~arrT() { if (own) stm::dealloc(this->d); }
00212
00213
00214
00215
00216 void alloc (tsize sz)
00217 {
00218 if (sz==this->s) return;
00219 if (own) stm::dealloc(this->d);
00220 this->s = sz;
00221 this->d = stm::alloc(sz);
00222 own = true;
00223 }
00224
00225
00226
00227 void allocAndFill (tsize sz, const T &inival)
00228 { alloc(sz); this->fill(inival); }
00229
00230
00231 void dealloc() {if (own) stm::dealloc(this->d); reset();}
00232
00233
00234
00235
00236 void resize (tsize sz)
00237 {
00238 using namespace std;
00239 if (sz==this->s) return;
00240 T *tmp = stm::alloc(sz);
00241 for (tsize m=0; m<min(sz,this->s); ++m)
00242 tmp[m]=this->d[m];
00243 if (own) stm::dealloc(this->d);
00244 this->s = sz;
00245 this->d = tmp;
00246 own = true;
00247 }
00248
00249
00250 arrT &operator= (const arrT &orig)
00251 {
00252 if (this==&orig) return *this;
00253 alloc (orig.s);
00254 for (tsize m=0; m<this->s; ++m) this->d[m] = orig.d[m];
00255 return *this;
00256 }
00257
00258
00259 template<typename T2> void copyFrom (const std::vector<T2> &orig)
00260 {
00261 alloc (orig.size());
00262 for (tsize m=0; m<this->s; ++m) this->d[m] = orig[m];
00263 }
00264
00265 template<typename T2> void copyTo (std::vector<T2> &vec) const
00266 {
00267 vec.clear(); vec.reserve(this->s);
00268 for (tsize m=0; m<this->s; ++m) vec.push_back(this->d[m]);
00269 }
00270
00271
00272
00273 template<typename T2> void copyFromPtr (const T2 *ptr, tsize sz)
00274 {
00275 alloc(sz);
00276 for (tsize m=0; m<this->s; ++m) this->d[m]=ptr[m];
00277 }
00278
00279
00280
00281 void transfer (arrT &other)
00282 {
00283 if (own) stm::dealloc(this->d);
00284 this->d=other.d;
00285 this->s=other.s;
00286 own=other.own;
00287 other.reset();
00288 }
00289
00290 void swap (arrT &other)
00291 {
00292 std::swap(this->d,other.d);
00293 std::swap(this->s,other.s);
00294 std::swap(own,other.own);
00295 }
00296 };
00297
00298
00299 template <typename T>
00300 class arr: public arrT<T,normalAlloc__<T> >
00301 {
00302 public:
00303
00304 arr() : arrT<T,normalAlloc__<T> >() {}
00305
00306 explicit arr(tsize sz) : arrT<T,normalAlloc__<T> >(sz) {}
00307
00308
00309 arr(tsize sz, const T &inival) : arrT<T,normalAlloc__<T> >(sz,inival) {}
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 arr (T *ptr, tsize sz): arrT<T,normalAlloc__<T> >(ptr,sz) {}
00322
00323
00324 arr (const arr &orig): arrT<T,normalAlloc__<T> >(orig) {}
00325 };
00326
00327
00328 template <typename T, int align>
00329 class arr_align: public arrT<T,alignAlloc__<T,align> >
00330 {
00331 public:
00332
00333 arr_align() : arrT<T,alignAlloc__<T,align> >() {}
00334
00335 explicit arr_align(tsize sz) : arrT<T,alignAlloc__<T,align> >(sz) {}
00336
00337
00338 arr_align(tsize sz, const T &inival)
00339 : arrT<T,alignAlloc__<T,align> >(sz,inival) {}
00340 };
00341
00342
00343
00344
00345
00346
00347 template <typename T, typename storageManager> class arr2T
00348 {
00349 private:
00350 tsize s1, s2;
00351 arrT<T, storageManager> d;
00352
00353 public:
00354
00355 arr2T() : s1(0), s2(0) {}
00356
00357 arr2T(tsize sz1, tsize sz2)
00358 : s1(sz1), s2(sz2), d(s1*s2) {}
00359
00360
00361
00362
00363 arr2T(T* p, tsize sz1, tsize sz2)
00364 : s1(sz1), s2(sz2), d(p, s1*s2) {}
00365 arr2T(tsize sz1, tsize sz2, const T &inival)
00366 : s1(sz1), s2(sz2), d (s1*s2)
00367 { fill(inival); }
00368
00369 arr2T(const arr2T &orig)
00370 : s1(orig.s1), s2(orig.s2), d(orig.d) {}
00371
00372 ~arr2T() {}
00373
00374
00375 tsize size1() const { return s1; }
00376
00377 tsize size2() const { return s2; }
00378
00379 tsize size () const { return s1*s2; }
00380
00381
00382
00383
00384
00385 void alloc (tsize sz1, tsize sz2)
00386 {
00387 if (sz1*sz2 != d.size())
00388 d.alloc(sz1*sz2);
00389 s1=sz1; s2=sz2;
00390 }
00391
00392
00393
00394
00395 void allocAndFill (tsize sz1, tsize sz2, const T &inival)
00396 { alloc(sz1,sz2); fill(inival); }
00397
00398
00399
00400
00401 void fast_alloc (tsize sz1, tsize sz2)
00402 {
00403 if (sz1*sz2<=d.size())
00404 { s1=sz1; s2=sz2; }
00405 else
00406 alloc(sz1,sz2);
00407 }
00408
00409 void dealloc () {d.dealloc(); s1=0; s2=0;}
00410
00411
00412 void fill (const T &val)
00413 { for (tsize m=0; m<s1*s2; ++m) d[m]=val; }
00414
00415
00416 void scale (const T &val)
00417 { for (tsize m=0; m<s1*s2; ++m) d[m]*=val; }
00418
00419
00420 arr2T &operator= (const arr2T &orig)
00421 {
00422 if (this==&orig) return *this;
00423 alloc (orig.s1, orig.s2);
00424 d = orig.d;
00425 return *this;
00426 }
00427
00428
00429 template<typename T2> T *operator[] (T2 n) {return &d[n*s2];}
00430
00431 template<typename T2> const T *operator[] (T2 n) const {return &d[n*s2];}
00432
00433
00434 template<typename T2, typename T3> T &operator() (T2 n1, T3 n2)
00435 {return d[n1*s2 + n2];}
00436
00437
00438 template<typename T2, typename T3> const T &operator() (T2 n1, T3 n2) const
00439 {return d[n1*s2 + n2];}
00440
00441
00442
00443 void minmax (T &minv, T &maxv) const
00444 {
00445 planck_assert(s1*s2>0,
00446 "trying to find min and max of a zero-sized array");
00447 minv=maxv=d[0];
00448 for (tsize m=1; m<s1*s2; ++m)
00449 {
00450 if (d[m]<minv) minv=d[m];
00451 if (d[m]>maxv) maxv=d[m];
00452 }
00453 }
00454
00455
00456 void swap (arr2T &other)
00457 {
00458 d.swap(other.d);
00459 std::swap(s1,other.s1);
00460 std::swap(s2,other.s2);
00461 }
00462
00463
00464
00465 template<typename T2, typename T3> bool conformable
00466 (const arr2T<T2,T3> &other) const
00467 { return (other.size1()==s1) && (other.size2()==s2); }
00468 };
00469
00470
00471
00472
00473 template <typename T>
00474 class arr2: public arr2T<T,normalAlloc__<T> >
00475 {
00476 public:
00477
00478 arr2() : arr2T<T,normalAlloc__<T> > () {}
00479
00480 arr2(tsize sz1, tsize sz2) : arr2T<T,normalAlloc__<T> > (sz1,sz2) {}
00481
00482
00483 arr2(T* p, tsize sz1, tsize sz2) : arr2T<T,normalAlloc__<T> > (p,sz1,sz2) {}
00484
00485
00486 arr2(tsize sz1, tsize sz2, const T &inival)
00487 : arr2T<T,normalAlloc__<T> > (sz1,sz2,inival) {}
00488 };
00489
00490
00491
00492
00493
00494 template <typename T, int align>
00495 class arr2_align: public arr2T<T,alignAlloc__<T,align> >
00496 {
00497 public:
00498
00499 arr2_align() : arr2T<T,alignAlloc__<T,align> > () {}
00500
00501 arr2_align(tsize sz1, tsize sz2)
00502 : arr2T<T,alignAlloc__<T,align> > (sz1,sz2) {}
00503
00504
00505 arr2_align(tsize sz1, tsize sz2, const T &inival)
00506 : arr2T<T,alignAlloc__<T,align> > (sz1,sz2,inival) {}
00507 };
00508
00509
00510
00511 template <typename T> class arr2b
00512 {
00513 private:
00514 tsize s1, s2;
00515 arr<T> d;
00516 arr<T *> d1;
00517
00518 void fill_d1()
00519 { for (tsize m=0; m<s1; ++m) d1[m] = &d[m*s2]; }
00520
00521 public:
00522
00523 arr2b() : s1(0), s2(0), d(0), d1(0) {}
00524
00525 arr2b(tsize sz1, tsize sz2)
00526 : s1(sz1), s2(sz2), d(s1*s2), d1(s1)
00527 { fill_d1(); }
00528
00529 arr2b(const arr2b &orig)
00530 : s1(orig.s1), s2(orig.s2), d(orig.d), d1(s1)
00531 { fill_d1(); }
00532
00533 ~arr2b() {}
00534
00535
00536 tsize size1() const { return s1; }
00537
00538 tsize size2() const { return s2; }
00539
00540 tsize size () const { return s1*s2; }
00541
00542
00543
00544 void alloc (tsize sz1, tsize sz2)
00545 {
00546 if ((s1==sz1) && (s2==sz2)) return;
00547 s1=sz1; s2=sz2;
00548 d.alloc(s1*s2);
00549 d1.alloc(s1);
00550 fill_d1();
00551 }
00552
00553 void dealloc () {d.dealloc(); d1.dealloc(); s1=0; s2=0;}
00554
00555
00556 void fill (const T &val)
00557 { d.fill(val); }
00558
00559
00560 arr2b &operator= (const arr2b &orig)
00561 {
00562 if (this==&orig) return *this;
00563 alloc (orig.s1, orig.s2);
00564 for (tsize m=0; m<s1*s2; ++m) d[m] = orig.d[m];
00565 return *this;
00566 }
00567
00568
00569 template<typename T2> T *operator[] (T2 n) {return d1[n];}
00570
00571 template<typename T2> const T *operator[] (T2 n) const {return d1[n];}
00572
00573
00574 T **p0() {return &d1[0];}
00575 };
00576
00577
00578
00579
00580
00581 template <typename T> class arr3
00582 {
00583 private:
00584 tsize s1, s2, s3, s2s3;
00585 arr<T> d;
00586
00587 public:
00588
00589 arr3() : s1(0), s2(0), s3(0), s2s3(0), d(0) {}
00590
00591 arr3(tsize sz1, tsize sz2, tsize sz3)
00592 : s1(sz1), s2(sz2), s3(sz3), s2s3(s2*s3), d(s1*s2*s3) {}
00593
00594 arr3(const arr3 &orig)
00595 : s1(orig.s1), s2(orig.s2), s3(orig.s3), s2s3(orig.s2s3), d(orig.d) {}
00596
00597 ~arr3() {}
00598
00599
00600 tsize size1() const { return s1; }
00601
00602 tsize size2() const { return s2; }
00603
00604 tsize size3() const { return s3; }
00605
00606 tsize size () const { return s1*s2*s3; }
00607
00608
00609
00610 void alloc (tsize sz1, tsize sz2, tsize sz3)
00611 {
00612 d.alloc(sz1*sz2*sz3);
00613 s1=sz1; s2=sz2; s3=sz3; s2s3=s2*s3;
00614 }
00615
00616 void dealloc () {d.dealloc(); s1=0; s2=0; s3=0; s2s3=0;}
00617
00618
00619 void fill (const T &val)
00620 { d.fill(val); }
00621
00622
00623 arr3 &operator= (const arr3 &orig)
00624 {
00625 if (this==&orig) return *this;
00626 alloc (orig.s1, orig.s2, orig.s3);
00627 d = orig.d;
00628 return *this;
00629 }
00630
00631
00632
00633 template<typename T2, typename T3, typename T4> T &operator()
00634 (T2 n1, T3 n2, T4 n3)
00635 {return d[n1*s2s3 + n2*s3 + n3];}
00636
00637
00638 template<typename T2, typename T3, typename T4> const T &operator()
00639 (T2 n1, T3 n2, T4 n3) const
00640 {return d[n1*s2s3 + n2*s3 + n3];}
00641
00642
00643 void swap (arr3 &other)
00644 {
00645 d.swap(other.d);
00646 std::swap(s1,other.s1);
00647 std::swap(s2,other.s2);
00648 std::swap(s3,other.s3);
00649 std::swap(s2s3,other.s2s3);
00650 }
00651
00652
00653
00654 template<typename T2> bool conformable (const arr3<T2> &other) const
00655 { return (other.size1()==s1)&&(other.size2()==s2)&&(other.size3()==s3); }
00656 };
00657
00658
00659
00660 #endif