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

array2d.h

Go to the documentation of this file.
00001 /*
00002 *
00003 * Template Numerical Toolkit (TNT): Two-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_ARRAY2D_H
00023 #define SPUC_ARRAY2D_H
00024 
00025 #include <cstdlib>
00026 #include <iostream>
00027 #ifdef SPUC_BOUNDS_CHECK
00028 #include <assert.h>
00029 #endif
00030 
00031 namespace SPUC
00032 {
00067 template <class T>
00068 class Array2D 
00069 {
00070 
00071 
00072   private:
00073     T** v_;                  
00074         int m_;
00075     int n_;
00076     int *ref_count_;
00077 
00078         void initialize_(int m, int n);
00079     void copy_(T* p, const T*  q, int len) const;
00080     void set_(const T& val);
00081     void destroy_();
00082         inline const T* begin_() const;
00083         inline T* begin_();
00084 
00085   public:
00086 
00087     typedef         T   value_type;
00088 
00089                Array2D();
00090                Array2D(int m, int n);
00091                Array2D(int m, int n,  T *a);
00092                Array2D(int m, int n, const T &a);
00093     inline Array2D(const Array2D &A);
00094         inline Array2D & operator=(const T &a);
00095         inline Array2D & operator=(const Array2D &A);
00096         inline Array2D & ref(const Array2D &A);
00097                Array2D copy() const;
00098                    Array2D & inject(const Array2D & A);
00099         inline T* operator[](int i);
00100         inline const T* operator[](int i) const;
00101         inline int dim1() const;
00102         inline int dim2() const;
00103         inline int ref_count() const;
00104         ~Array2D();
00105         // NEW
00106         inline int cols() const;
00107         inline int rows() const;
00108         Array2D<T>& newsize(int M, int N) { return(set_size(M,N)); }
00109         Array2D<T>& set_size(int M, int N) {
00110                 if (dim1() == M && dim2() == N)
00111             return *this;
00112         destroy_();
00113         initialize_(M,N);
00114         return *this;
00115         }
00116         // NEW
00117 
00118 };
00119 
00120 
00127 template <class T>
00128 Array2D<T>::Array2D(const Array2D<T> &A) : v_(A.v_), m_(A.m_), 
00129         n_(A.n_), ref_count_(A.ref_count_)
00130 {
00131         (*ref_count_)++;
00132 }
00133 
00134 
00135 
00147 template <class T>
00148 Array2D<T>::Array2D(int m, int n) : v_(0), m_(m), n_(n), ref_count_(0)
00149 {
00150         initialize_(m,n);
00151         ref_count_ = new int;
00152         *ref_count_ = 1;
00153 }
00154 
00155 
00156 
00166 template <class T>
00167 Array2D<T>::Array2D(int m, int n, const T &val) : v_(0), m_(m), n_(n) ,
00168         ref_count_(0)
00169 {
00170         initialize_(m,n);
00171         set_(val);
00172         ref_count_ = new int;
00173         *ref_count_ = 1;
00174 
00175 }
00176 
00189 template <class T>
00190 Array2D<T>::Array2D(int m, int n, T *a) : v_(0), m_(m), n_(n) ,
00191         ref_count_(0)
00192 {
00193         T* p = a;
00194         v_ = new T*[m];
00195         for (int i=0; i<m; i++)
00196         {
00197                 v_[i] = p;
00198                 p += n;
00199         }
00200         ref_count_ = new int;
00201         *ref_count_ = 2;                /* this avoid destorying original data. */
00202 
00203 }
00204 
00205 
00217 template <class T>
00218 inline T* Array2D<T>::operator[](int i) 
00219 { 
00220 #ifdef SPUC_BOUNDS_CHECK
00221         assert(i >= 0);
00222         assert(i < m_);
00223 #endif
00224 
00225 return v_[i]; 
00226 
00227 }
00228 
00229 template <class T>
00230 inline const T* Array2D<T>::operator[](int i) const { return v_[i]; }
00231 
00235 template <class T>
00236 Array2D<T> & Array2D<T>::operator=(const T &a)
00237 {
00238         set_(a);
00239         return *this;
00240 }
00247 template <class T>
00248 Array2D<T> Array2D<T>::copy() const
00249 {
00250         Array2D A(m_, n_);
00251         copy_(A.begin_(), begin_(), m_*n_);
00252 
00253         return A;
00254 }
00255 
00256 
00280 template <class T>
00281 Array2D<T> & Array2D<T>::inject(const Array2D &A)
00282 {
00283         if (A.m_ == m_ &&  A.n_ == n_)
00284                 copy_(begin_(), A.begin_(), m_*n_);
00285 
00286         return *this;
00287 }
00288 
00289 
00290 
00291 
00292 
00303 template <class T>
00304 Array2D<T> & Array2D<T>::ref(const Array2D<T> &A)
00305 {
00306         if (this != &A)
00307         {
00308                 (*ref_count_) --;
00309                 if ( *ref_count_ < 1 )
00310                 {
00311                         destroy_();
00312                 }
00313 
00314                 m_ = A.m_;
00315                 n_ = A.n_;
00316                 v_ = A.v_;
00317                 ref_count_ = A.ref_count_;
00318 
00319                 (*ref_count_) ++ ;
00320                 
00321         }
00322         return *this;
00323 }
00324 
00328 template <class T>
00329 Array2D<T> & Array2D<T>::operator=(const Array2D<T> &A)
00330 {
00331         return ref(A);
00332 }
00333 
00338 template <class T> inline int Array2D<T>::dim1() const { return m_; }
00339 template <class T> inline int Array2D<T>::rows() const { return m_; }
00340 
00345 template <class T> inline int Array2D<T>::dim2() const { return n_; }
00346 template <class T> inline int Array2D<T>::cols() const { return n_; }
00347 
00348 
00353 template <class T>
00354 inline int Array2D<T>::ref_count() const
00355 {
00356         return *ref_count_;
00357 }
00358 
00359 template <class T>
00360 Array2D<T>::~Array2D()
00361 {
00362         (*ref_count_) --;
00363 
00364         if (*ref_count_ < 1)
00365                 destroy_();
00366 }
00367 
00368 /* private internal functions */
00369 
00370 template <class T>
00371 void Array2D<T>::initialize_(int m, int n)
00372 {
00373 
00374 
00375         T* p = new T[m*n];
00376         v_ = new T*[m];
00377         for (int i=0; i<m; i++)
00378         {
00379                 v_[i] = p;
00380                 p+=n;
00381         }
00382         m_ = m;
00383         n_ = n;
00384 }
00385 
00386 template <class T>
00387 void Array2D<T>::set_(const T& a)
00388 {
00389         T *begin = &v_[0][0];
00390         T *end = begin+ m_*n_;
00391 
00392         for (T* p=begin; p<end; p++)
00393                 *p = a;
00394 
00395 }
00396 
00397 template <class T>
00398 void Array2D<T>::copy_(T* p, const T* q, int len) const
00399 {
00400         T *end = p + len;
00401         while (p<end )
00402                 *p++ = *q++;
00403 
00404 }
00405 
00406 template <class T>
00407 void Array2D<T>::destroy_()
00408 {
00409 
00410         if (v_ != 0)
00411         {
00412                 delete[] (v_[0]);
00413                 delete[] (v_);
00414         }
00415 
00416         if (ref_count_ != 0)
00417                 delete ref_count_;
00418 }
00419 
00423 template <class T>
00424 const T* Array2D<T>::begin_() const { return &(v_[0][0]); }
00425 
00429 template <class T>
00430 T* Array2D<T>::begin_() { return &(v_[0][0]); }
00431 
00435 template <class T>
00436 Array2D<T>::Array2D() : v_(0), m_(0), n_(0) 
00437 {
00438         ref_count_ = new int;
00439         *ref_count_ = 1;
00440 }
00441 
00442 
00443 
00444 
00445 
00446 } /* namespace SPUC */
00447 
00448 #endif
00449 /* SPUC_ARRAY2D_H */
00450 

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