Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

array3d.h

Go to the documentation of this file.
00001 /*
00002 *
00003 * Template Numerical Toolkit (TNT): Three-dimensional numerical array
00004 *
00005 * Mathematical and Computational Sciences Division
00006 * National Institute of Technology,
00007 * Gaithersburg, MD USA
00008 *
00009 *
00010 * This software was developed at the National Institute of Standards and
00011 * Technology (NIST) by employees of the Federal Government in the course
00012 * of their official duties. Pursuant to title 17 Section 105 of the
00013 * United States Code, this software is not subject to copyright protection
00014 * and is in the public domain. NIST assumes no responsibility whatsoever for
00015 * its use by other parties, and makes no guarantees, expressed or implied,
00016 * about its quality, reliability, or any other characteristic.
00017 *
00018 */
00019 
00020 
00021 
00022 #ifndef SPUC_ARRAY3D_H
00023 #define SPUC_ARRAY3D_H
00024 
00025 #include <cstdlib>
00026 #include <iostream>
00027 #ifdef SPUC_BOUNDS_CHECK
00028 #include <assert.h>
00029 #endif
00030 
00031 namespace SPUC {
00067 template <class T>
00068 class Array3D 
00069 {
00070 
00071 
00072   private:
00073     T*** v_;                  
00074         int m_;
00075     int n_;
00076         int k_;
00077     int *ref_count_;
00078 
00079         void initialize_(T* data, int m, int n, int k);
00080     void copy_(T* p, const T*  q, int len) const;
00081     void set_(const T& val);
00082     void destroy_();
00083         inline const T* begin_() const;
00084         inline T* begin_();
00085 
00086   public:
00087 
00088     typedef         T   value_type;
00089 
00090                Array3D();
00091                Array3D(int m, int n, int k);
00092                Array3D(int m, int n, int k,  T *a);
00093                Array3D(int m, int n, int k, const T &a);
00094     inline Array3D(const Array3D &A);
00095         inline Array3D & operator=(const T &a);
00096         inline Array3D & operator=(const Array3D &A);
00097         inline Array3D & ref(const Array3D &A);
00098                Array3D copy() const;
00099                    Array3D & inject(const Array3D & A);
00100         inline T** operator[](int i);
00101         inline const T* const * operator[](int i) const;
00102         inline int dim1() const;
00103         inline int dim2() const;
00104         inline int dim3() const;
00105         inline int ref_count() const;
00106                ~Array3D();
00107 
00108 
00109 };
00110 
00111 
00118 template <class T>
00119 Array3D<T>::Array3D(const Array3D<T> &A) : v_(A.v_), m_(A.m_), 
00120         n_(A.n_), k_(A.k_), ref_count_(A.ref_count_)
00121 {
00122         (*ref_count_)++;
00123 }
00124 
00125 
00126 
00139 template <class T>
00140 Array3D<T>::Array3D(int m, int n, int k) : v_(0), m_(m), n_(n), k_(k), ref_count_(0)
00141 {
00142         initialize_(new T[m*n*k], m,n,k);
00143         ref_count_ = new int;
00144         *ref_count_ = 1;
00145 }
00146 
00147 
00148 
00159 template <class T>
00160 Array3D<T>::Array3D(int m, int n, int k, const T &val) : v_(0), m_(m), n_(n) ,
00161         k_(k), ref_count_(0)
00162 {
00163         initialize_(new T[m*n*k], m,n,k);
00164         set_(val);
00165         ref_count_ = new int;
00166         *ref_count_ = 1;
00167 
00168 }
00169 
00184 template <class T>
00185 Array3D<T>::Array3D(int m, int n, int k, T *a) : v_(0), m_(m), n_(n) ,
00186         k_(k), ref_count_(0)
00187 {
00188         initialize_(a, m, n, k);
00189         ref_count_ = new int;
00190         *ref_count_ = 2;                /* this avoids destorying original data. */
00191 
00192 }
00193 
00194 
00204 template <class T>
00205 inline T** Array3D<T>::operator[](int i) 
00206 { 
00207 #ifdef SPUC_BOUNDS_CHECK
00208         assert(i >= 0);
00209         assert(i < m_);
00210 #endif
00211 
00212 return v_[i]; 
00213 
00214 }
00215 
00216 template <class T>
00217 inline const T* const * Array3D<T>::operator[](int i) const { return v_[i]; }
00218 
00222 template <class T>
00223 Array3D<T> & Array3D<T>::operator=(const T &a)
00224 {
00225         set_(a);
00226         return *this;
00227 }
00234 template <class T>
00235 Array3D<T> Array3D<T>::copy() const
00236 {
00237         Array3D A(m_, n_, k_);
00238         copy_(A.begin_(), begin_(), m_*n_*k_);
00239 
00240         return A;
00241 }
00242 
00243 
00267 template <class T>
00268 Array3D<T> & Array3D<T>::inject(const Array3D &A)
00269 {
00270         if (A.m_ == m_ &&  A.n_ == n_)
00271                 copy_(begin_(), A.begin_(), m_*n_);
00272 
00273         return *this;
00274 }
00275 
00276 
00277 
00278 
00279 
00290 template <class T>
00291 Array3D<T> & Array3D<T>::ref(const Array3D<T> &A)
00292 {
00293         if (this != &A)
00294         {
00295                 (*ref_count_) --;
00296                 if ( *ref_count_ < 1 )
00297                 {
00298                         destroy_();
00299                 }
00300 
00301                 m_ = A.m_;
00302                 n_ = A.n_;
00303                 k_ = A.k_;
00304                 v_ = A.v_;
00305                 ref_count_ = A.ref_count_;
00306 
00307                 (*ref_count_) ++ ;
00308                 
00309         }
00310         return *this;
00311 }
00312 
00316 template <class T>
00317 Array3D<T> & Array3D<T>::operator=(const Array3D<T> &A)
00318 {
00319         return ref(A);
00320 }
00321 
00325 template <class T>
00326 inline int Array3D<T>::dim1() const { return m_; }
00327 
00331 template <class T>
00332 inline int Array3D<T>::dim2() const { return n_; }
00333 
00337 template <class T>
00338 inline int Array3D<T>::dim3() const { return k_; }
00339 
00340 
00345 template <class T>
00346 inline int Array3D<T>::ref_count() const
00347 {
00348         return *ref_count_;
00349 }
00350 
00351 template <class T>
00352 Array3D<T>::~Array3D()
00353 {
00354         (*ref_count_) --;
00355 
00356         if (*ref_count_ < 1)
00357                 destroy_();
00358 }
00359 
00360 /* private internal functions */
00361 
00362 template <class T>
00363 void Array3D<T>::initialize_( T* data, int m, int n, int k)
00364 {
00365 
00366         v_ = new T**[m];
00367         v_[0] = new T*[m*n];
00368         v_[0][0] = data;
00369 
00370 
00371         for (int i=0; i<m; i++)
00372         {
00373                 v_[i] = v_[0] + i * n;
00374                 for (int j=0; j<n; j++)
00375                         v_[i][j] = v_[0][0] + i * (n*k) + j * k;
00376         }
00377 
00378         m_ = m;
00379         n_ = n;
00380         k_ = k;
00381 }
00382 
00383 template <class T>
00384 void Array3D<T>::set_(const T& a)
00385 {
00386         T *begin = &(v_[0][0][0]);
00387         T *end = begin+ m_*n_*k_;
00388 
00389         for (T* p=begin; p<end; p++)
00390                 *p = a;
00391 
00392 }
00393 
00394 template <class T>
00395 void Array3D<T>::copy_(T* p, const T* q, int len) const
00396 {
00397         T *end = p + len;
00398         while (p<end )
00399                 *p++ = *q++;
00400 
00401 }
00402 
00403 template <class T>
00404 void Array3D<T>::destroy_()
00405 {
00406 
00407         if (v_ != 0)
00408         {
00409                 delete[] (v_[0][0]);
00410                 delete[] (v_[0]);
00411                 delete[] (v_);
00412         }
00413 
00414         if (ref_count_ != 0)
00415                 delete ref_count_;
00416 }
00417 
00421 template <class T>
00422 const T* Array3D<T>::begin_() const { return &(v_[0][0][0]); }
00423 
00427 template <class T>
00428 T* Array3D<T>::begin_() { return &(v_[0][0][0]); }
00429 
00433 template <class T>
00434 Array3D<T>::Array3D() : v_(0), m_(0), n_(0) 
00435 {
00436         ref_count_ = new int;
00437         *ref_count_ = 1;
00438 }
00439 
00440 } /* namespace SPUC */
00441 
00442 #endif
00443 /* SPUC_ARRAY3D_H */
00444 

Generated on Fri Sep 16 11:02:17 2005 for spuc by  doxygen 1.4.4