Main Page | Modules | Alphabetical List | Class List | File List | Class Members | File Members

arr.h

Go to the documentation of this file.
00001 /*
00002  *  This file is part of Healpix_cxx.
00003  *
00004  *  Healpix_cxx is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  Healpix_cxx is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with Healpix_cxx; if not, write to the Free Software
00016  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017  *
00018  *  For more information about HEALPix, see http://healpix.jpl.nasa.gov
00019  */
00020 
00021 /*
00022  *  Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
00023  *  and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
00024  *  (DLR).
00025  */
00026 
00027 /*! \file arr.h
00028  *  Various high-performance array classes used by the Planck LevelS package.
00029  *
00030  *  Copyright (C) 2002, 2003, 2004, 2005 Max-Planck-Society
00031  *  \author Martin Reinecke
00032  */
00033 
00034 #ifndef PLANCK_ARR_H
00035 #define PLANCK_ARR_H
00036 
00037 #include "cxxutils.h"
00038 #include <algorithm>
00039 
00040 /*! \defgroup arraygroup Array classes */
00041 /*! \{ */
00042 
00043 /*! An array whose size is known at compile time. Very useful for storing
00044     small arrays on the stack, without need for \a new() and \a delete(). */
00045 template <typename T, unsigned int sz> class fix_arr
00046   {
00047   private:
00048     T d[sz];
00049 
00050   public:
00051     /*! Returns the size of the array. */
00052     long size() const { return sz; }
00053 
00054     /*! Returns a reference to element \a #n */
00055     T &operator[] (long n) {return d[n];}
00056     /*! Returns a reference to element \a #n */
00057     T &operator[] (int n) {return d[n];}
00058     /*! Returns a constant reference to element \a #n */
00059     const T &operator[] (long n) const {return d[n];}
00060     /*! Returns a constant reference to element \a #n */
00061     const T &operator[] (int n) const {return d[n];}
00062   };
00063 
00064 
00065 /*! One-dimensional array type. */
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     /*! Creates a zero-sized array. */
00083     arr() : s(0), d(0) {}
00084     /*! Creates an array with \a sz entries. */
00085     arr(long sz) : s(sz), d (s>0 ? new T[s] : 0) {}
00086     /*! Creates an array with \a sz entries, and initializes them with
00087         \a inival. */
00088     arr(long sz, const T&inival) : s(sz), d (s>0 ? new T[s] : 0)
00089       { fill(inival); }
00090     /*! Creates an array which is a copy of \a orig. The data in \a orig
00091         is duplicated. */
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     /*! Frees the memory allocated by the object. */
00095     ~arr() { delete[] d; }
00096 
00097     /*! Returns the current array size. */
00098     long size() const { return s; }
00099 
00100     /*! Allocates space for \a sz elements. The content of the array is
00101         undefined on exit. \a sz can be 0. If \a sz is the
00102         same as the current size, no reallocation is performed. */
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     /*! Deallocates the memory held by the array, and sets the array size
00111         to 0. */
00112     void dealloc () {delete[] d; d=0; s=0;}
00113 
00114     /*! Writes \a val into every element of the array. */
00115     void fill (const T &val)
00116       { for (long m=0; m<s; ++m) d[m]=val; }
00117 
00118     /*! Changes the array to be a copy of \a orig. */
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     /*! Returns a reference to element \a #n */
00134     T &operator[] (long n) {return d[n];}
00135     /*! Returns a reference to element \a #n */
00136     T &operator[] (int n) {return d[n];}
00137     /*! Returns a constant reference to element \a #n */
00138     const T &operator[] (long n) const {return d[n];}
00139     /*! Returns a constant reference to element \a #n */
00140     const T &operator[] (int n) const {return d[n];}
00141 #endif
00142     /*! Returns a pointer to the first element,
00143         or 0 if the array is zero-sized. */
00144     operator T *() { return d; }
00145     /*! Returns a constant pointer to the first element,
00146         or 0 if the array is zero-sized. */
00147     operator const T *() const { return d; }
00148 
00149     T *begin() { return d; }
00150     T *end() { return d+s; }
00151 
00152     /*! Sorts the elements in the array, in ascending order. */
00153     void sort()
00154       { std::sort (d,d+s); }
00155 
00156     /*! Returns the minimum and maximum entry in \a minv and \a maxv,
00157         respectively. Does nothing if the array is zero-sized. */
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     /*! Assigns the contents and size of \a other to the array. On exit,
00170         \a other is yero-sized. */
00171     void transfer (arr &other)
00172       { delete[] d; d=other.d; s=other.s; other.d=0; other.s=0; }
00173     /*! Swaps contents and size with \a other. */
00174     void swap (arr &other)
00175       { std::swap(d,other.d); std::swap(s,other.s); }
00176   };
00177 
00178 /*! Two-dimensional array type. The storage ordering is the same as in C.
00179     An entry is located by adress arithmetic, not by double dereferencing.
00180     The indices start at zero. */
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     /*! Creates a zero-sized array. */
00198     arr2() : s1(0), s2(0), cap(0), d(0) {}
00199     /*! Creates an array with the dimensions \a sz1 and \a sz2. */
00200     arr2(long sz1, long sz2)
00201       : s1(sz1), s2(sz2), cap(s1*s2), d (cap>0 ? new T[cap] : 0) {}
00202     /*! Creates the array as a copy of \a orig. */
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     /*! Frees the memory associated with the array. */
00207     ~arr2() { delete[] d; }
00208 
00209     /*! Returns the first array dimension. */
00210     long size1() const { return s1; }
00211     /*! Returns the second array dimension. */
00212     long size2() const { return s2; }
00213     /*! Returns the total array size, i.e. the product of both dimensions. */
00214     long size () const { return s1*s2; }
00215 
00216     /*! Allocates space for an array with \a sz1*sz2 elements.
00217         The content of the array is undefined on exit.
00218         \a sz1 or \a sz2 can be 0. If \a sz1*sz2 is the same as the
00219         currently allocated space, no reallocation is performed. */
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     /*! Allocates space for an array with \a sz1*sz2 elements.
00231         The content of the array is undefined on exit.
00232         \a sz1 or \a sz2 can be 0. If \a sz1*sz2 is smaller than the
00233         currently allocated space, no reallocation is performed. */
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     /*! Deallocates the space and makes the array zero-sized. */
00242     void dealloc () {delete[] d; d=0; s1=0; s2=0; cap=0;}
00243 
00244     /*! Sets all array elements to \a val. */
00245     void fill (const T &val)
00246       { for (long m=0; m<s1*s2; ++m) d[m]=val; }
00247 
00248     /*! Changes the array to be a copy of \a orig. */
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     /*! Returns a pointer to the beginning of slice \a #n. */
00264     T *operator[] (long n) {return &d[n*s2];}
00265     /*! Returns a pointer to the beginning of slice \a #n. */
00266     T *operator[] (int n) {return &d[n*s2];}
00267     /*! Returns a constant pointer to the beginning of slice \a #n. */
00268     const T *operator[] (long n) const {return &d[n*s2];}
00269     /*! Returns a constant pointer to the beginning of slice \a #n. */
00270     const T *operator[] (int n) const {return &d[n*s2];}
00271 #endif
00272 
00273     /*! Returns the minimum and maximum entry in \a minv and \a maxv,
00274         respectively. Does nothing if the array is zero-sized. */
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     /*! Swaps contents and sizes with \a other. */
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 /*! Two-dimensional array type. An entry is located by double dereferencing,
00297     i.e. via an array of pointers. The indices start at zero. */
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     /*! Creates a zero-sized array. */
00316     arr2b() : s1(0), s2(0), d(0), d1(0) {}
00317     /*! Creates an array with the dimensions \a sz1 and \a sz2. */
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     /*! Creates the array as a copy of \a orig. */
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     /*! Frees the memory associated with the array. */
00330     ~arr2b() { delete[] d; delete[] d1; }
00331 
00332     /*! Returns the first array dimension. */
00333     long size1() const { return s1; }
00334     /*! Returns the second array dimension. */
00335     long size2() const { return s2; }
00336     /*! Returns the total array size, i.e. the product of both dimensions. */
00337     long size () const { return s1*s2; }
00338 
00339     /*! Allocates space for an array with \a sz1*sz2 elements.
00340         The content of the array is undefined on exit. */
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     /*! Deallocates the space and makes the array zero-sized. */
00350     void dealloc () {delete[] d; delete[] d1; d=0; d1=0; s1=0; s2=0;}
00351 
00352     /*! Sets all array elements to \a val. */
00353     void fill (const T &val)
00354       { for (long m=0; m<s1*s2; ++m) d[m]=val; }
00355 
00356     /*! Changes the array to be a copy of \a orig. */
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     /*! Returns a pointer to the beginning of slice \a #n. */
00372     T *operator[] (long n) {return d1[n];}
00373     /*! Returns a pointer to the beginning of slice \a #n. */
00374     T *operator[] (int n) {return d1[n];}
00375     /*! Returns a constant pointer to the beginning of slice \a #n. */
00376     const T *operator[] (long n) const {return d1[n];}
00377     /*! Returns a constant pointer to the beginning of slice \a #n. */
00378     const T *operator[] (int n) const {return d1[n];}
00379 #endif
00380     /*! Returns a pointer to the beginning of the pointer array. */
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

Generated on Fri Jul 8 09:37:14 2005 for LevelS C++ support library