NASA - Jet Propulsion Laboratory
    + View the NASA Portal
Search JPL
Jet Propulsion Laboratory Home Earth Solar System Stars & Galaxies Technology
Introduction Background Software Links

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, 2006, 2007 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     template<typename T2> T &operator[] (T2 n) {return d[n];}
00056     /*! Returns a constant reference to element \a #n */
00057     template<typename T2> const T &operator[] (T2 n) const {return d[n];}
00058   };
00059 
00060 
00061 /*! One-dimensional array type. */
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     /*! Creates a zero-sized array. */
00083     arr() : s(0), d(0), own(true) {}
00084     /*! Creates an array with \a sz entries. */
00085     arr(long sz) : s(sz), d (s>0 ? new T[s] : 0), own(true) {}
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), own(true)
00089       { fill(inival); }
00090     /*! Creates an array with \a sz entries, which uses the memory pointed
00091         to by \a ptr.
00092         \note \a ptr will <i>not</i> be deallocated by the destructor.
00093         \warning Only use this if you REALLY know what you are doing.
00094         In particular, this is only safely usable if
00095           <ul>
00096           <li>\a T is a POD type</li>
00097           <li>\a ptr survives during the lifetime of the array object</li>
00098           <li>\a ptr is not subject to garbage collection</li>
00099           </ul>
00100         Other restrictions may apply. You have been warned. */
00101     arr (T *ptr, long sz): s(sz), d(ptr), own(false) {}
00102     /*! Creates an array which is a copy of \a orig. The data in \a orig
00103         is duplicated. */
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     /*! Frees the memory allocated by the object. */
00107     ~arr() { if (own) delete[] d; }
00108 
00109     /*! Returns the current array size. */
00110     long size() const { return s; }
00111 
00112     /*! Allocates space for \a sz elements. The content of the array is
00113         undefined on exit. \a sz can be 0. If \a sz is the
00114         same as the current size, no reallocation is performed. */
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     /*! Deallocates the memory held by the array, and sets the array size
00124         to 0. */
00125     void dealloc () {if (own) delete[] d; reset();}
00126 
00127     /*! Writes \a val into every element of the array. */
00128     void fill (const T &val)
00129       { for (long m=0; m<s; ++m) d[m]=val; }
00130 
00131     /*! Changes the array to be a copy of \a orig. */
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     /*! Returns a reference to element \a #n */
00146     template<typename T2> T &operator[] (T2 n) {return d[n];}
00147     /*! Returns a constant reference to element \a #n */
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     /*! Sorts the elements in the array, in ascending order. */
00155     void sort()
00156       { std::sort (d,d+s); }
00157 
00158     /*! Returns the minimum and maximum entry in \a minv and \a maxv,
00159         respectively. Throws an exception if the array is zero-sized. */
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     /*! Assigns the contents and size of \a other to the array. On exit,
00172         \a other is yero-sized. */
00173     void transfer (arr &other)
00174       { if (own) delete[] d; d=other.d; s=other.s; own=other.own; other.reset(); }
00175     /*! Swaps contents and size with \a other. */
00176     void swap (arr &other)
00177       { std::swap(d,other.d); std::swap(s,other.s); std::swap(own,other.own);}
00178   };
00179 
00180 /*! Two-dimensional array type. The storage ordering is the same as in C.
00181     An entry is located by address arithmetic, not by double dereferencing.
00182     The indices start at zero. */
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     /*! Creates a zero-sized array. */
00200     arr2() : s1(0), s2(0) {}
00201     /*! Creates an array with the dimensions \a sz1 and \a sz2. */
00202     arr2(long sz1, long sz2)
00203       : s1(sz1), s2(sz2), d(s1*s2) {}
00204     /*! Creates the array as a copy of \a orig. */
00205     arr2(const arr2 &orig)
00206       : s1(orig.s1), s2(orig.s2), d(orig.d) {}
00207     /*! Frees the memory associated with the array. */
00208     ~arr2() {}
00209 
00210     /*! Returns the first array dimension. */
00211     long size1() const { return s1; }
00212     /*! Returns the second array dimension. */
00213     long size2() const { return s2; }
00214     /*! Returns the total array size, i.e. the product of both dimensions. */
00215     long size () const { return s1*s2; }
00216 
00217     /*! Allocates space for an array with \a sz1*sz2 elements.
00218         The content of the array is undefined on exit.
00219         \a sz1 or \a sz2 can be 0. If \a sz1*sz2 is the same as the
00220         currently allocated space, no reallocation is performed. */
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     /*! Allocates space for an array with \a sz1*sz2 elements.
00228         The content of the array is undefined on exit.
00229         \a sz1 or \a sz2 can be 0. If \a sz1*sz2 is smaller than the
00230         currently allocated space, no reallocation is performed. */
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     /*! Deallocates the space and makes the array zero-sized. */
00239     void dealloc () {d.dealloc(); s1=0; s2=0;}
00240 
00241     /*! Sets all array elements to \a val. */
00242     void fill (const T &val)
00243       { d.fill(val); }
00244 
00245     /*! Changes the array to be a copy of \a orig. */
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     /*! Returns a pointer to the beginning of slice \a #n. */
00261     template<typename T2> T *operator[] (T2 n) {return &d[n*s2];}
00262     /*! Returns a constant pointer to the beginning of slice \a #n. */
00263     template<typename T2> const T *operator[] (T2 n) const {return &d[n*s2];}
00264 #endif
00265 
00266     /*! Returns the minimum and maximum entry in \a minv and \a maxv,
00267         respectively. Throws an exception if the array is zero-sized. */
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     /*! Swaps contents and sizes with \a other. */
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 /*! Two-dimensional array type. An entry is located by double dereferencing,
00290     i.e. via an array of pointers. The indices start at zero. */
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     /*! Creates a zero-sized array. */
00312     arr2b() : s1(0), s2(0), d(0), d1(0) {}
00313     /*! Creates an array with the dimensions \a sz1 and \a sz2. */
00314     arr2b(long sz1, long sz2)
00315       : s1(sz1), s2(sz2), d(s1*s2), d1(s1)
00316       { fill_d1(); }
00317     /*! Creates the array as a copy of \a orig. */
00318     arr2b(const arr2b &orig)
00319       : s1(orig.s1), s2(orig.s2), d(orig.d), d1(s1)
00320       { fill_d1(); }
00321     /*! Frees the memory associated with the array. */
00322     ~arr2b() {}
00323 
00324     /*! Returns the first array dimension. */
00325     long size1() const { return s1; }
00326     /*! Returns the second array dimension. */
00327     long size2() const { return s2; }
00328     /*! Returns the total array size, i.e. the product of both dimensions. */
00329     long size () const { return s1*s2; }
00330 
00331     /*! Allocates space for an array with \a sz1*sz2 elements.
00332         The content of the array is undefined on exit. */
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     /*! Deallocates the space and makes the array zero-sized. */
00342     void dealloc () {d.dealloc(); d1.dealloc(); s1=0; s2=0;}
00343 
00344     /*! Sets all array elements to \a val. */
00345     void fill (const T &val)
00346       { d.fill(val); }
00347 
00348     /*! Changes the array to be a copy of \a orig. */
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     /*! Returns a pointer to the beginning of slice \a #n. */
00363     template<typename T2> T *operator[] (T2 n) {return d1[n];}
00364     /*! Returns a constant pointer to the beginning of slice \a #n. */
00365     template<typename T2> const T *operator[] (T2 n) const {return d1[n];}
00366 #endif
00367     /*! Returns a pointer to the beginning of the pointer array. */
00368     T **p0() {return &d1[0];}
00369   };
00370 
00371 
00372 /*! Three-dimensional array type. The storage ordering is the same as in C.
00373     An entry is located by address arithmetic, not by multiple dereferencing.
00374     The indices start at zero. */
00375 template <typename T> class arr3
00376   {
00377   private:
00378     long s1, s2, s3, s2s3;
00379     arr<T> d;
00380 
00381   public:
00382     /*! Creates a zero-sized array. */
00383     arr3() : s1(0), s2(0), s3(0), s2s3(0), d(0) {}
00384     /*! Creates an array with the dimensions \a sz1, \a sz2 and \a sz3. */
00385     arr3(long sz1, long sz2, long sz3)
00386       : s1(sz1), s2(sz2), s3(sz3), s2s3(s2*s3), d(s1*s2*s3) {}
00387     /*! Creates the array as a copy of \a orig. */
00388     arr3(const arr3 &orig)
00389       : s1(orig.s1), s2(orig.s2), s3(orig.s3), s2s3(orig.s2s3), d(orig.d) {}
00390     /*! Frees the memory associated with the array. */
00391     ~arr3() {}
00392 
00393     /*! Returns the first array dimension. */
00394     long size1() const { return s1; }
00395     /*! Returns the second array dimension. */
00396     long size2() const { return s2; }
00397     /*! Returns the third array dimension. */
00398     long size3() const { return s3; }
00399     /*! Returns the total array size, i.e. the product of all dimensions. */
00400     long size () const { return s1*s2*s3; }
00401 
00402     /*! Allocates space for an array with \a sz1*sz2*sz3 elements.
00403         The content of the array is undefined on exit. */
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     /*! Deallocates the space and makes the array zero-sized. */
00410     void dealloc () {d.dealloc(); s1=0; s2=0; s3=0; s2s3=0;}
00411 
00412     /*! Sets all array elements to \a val. */
00413     void fill (const T &val)
00414       { d.fill(val); }
00415 
00416     /*! Changes the array to be a copy of \a orig. */
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     /*! Returns a reference to the element with the indices
00426         \a n1, \a n2 and \a n3. */
00427     template<typename T2> T &operator() (T2 n1, T2 n2, T2 n3)
00428       {return d[n1*s2s3 + n2*s3 + n3];}
00429     /*! Returns a constant reference to the element with the indices
00430         \a n1, \a n2 and \a n3. */
00431     template<typename T2> const T &operator() (T2 n1, T2 n2, T2 n3) const
00432       {return d[n1*s2s3 + n2*s3 + n3];}
00433 
00434     /*! Swaps contents and sizes with \a other. */
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

Generated on Fri Jun 18 16:12:29 2010 for LevelS C++ support library
Privacy / Copyright
FIRST GOV Contact: NASA Home Page Site Manager:
Webmaster:

CL 03-2650