Blender  V2.59
tnt_array2d.h
Go to the documentation of this file.
00001 
00004 /*
00005 *
00006 * Template Numerical Toolkit (TNT)
00007 *
00008 * Mathematical and Computational Sciences Division
00009 * National Institute of Technology,
00010 * Gaithersburg, MD USA
00011 *
00012 *
00013 * This software was developed at the National Institute of Standards and
00014 * Technology (NIST) by employees of the Federal Government in the course
00015 * of their official duties. Pursuant to title 17 Section 105 of the
00016 * United States Code, this software is not subject to copyright protection
00017 * and is in the public domain. NIST assumes no responsibility whatsoever for
00018 * its use by other parties, and makes no guarantees, expressed or implied,
00019 * about its quality, reliability, or any other characteristic.
00020 *
00021 */
00022 
00023 
00024 
00025 #ifndef TNT_ARRAY2D_H
00026 #define TNT_ARRAY2D_H
00027 
00028 #include <cstdlib>
00029 #include <iostream>
00030 #ifdef TNT_BOUNDS_CHECK
00031 #include <assert.h>
00032 #endif
00033 
00034 #include "tnt_array1d.h"
00035 
00036 namespace TNT
00037 {
00038 
00039 template <class T>
00040 class Array2D 
00041 {
00042 
00043 
00044   private:
00045 
00046 
00047 
00048         Array1D<T> data_;
00049         Array1D<T*> v_;
00050         int m_;
00051     int n_;
00052 
00053   public:
00054 
00055     typedef         T   value_type;
00056                Array2D();
00057                Array2D(int m, int n);
00058                Array2D(int m, int n,  T *a);
00059                Array2D(int m, int n, const T &a);
00060     inline Array2D(const Array2D &A);
00061         inline operator T**();
00062         inline operator const T**();
00063         inline Array2D & operator=(const T &a);
00064         inline Array2D & operator=(const Array2D &A);
00065         inline Array2D & ref(const Array2D &A);
00066                Array2D copy() const;
00067                    Array2D & inject(const Array2D & A);
00068         inline T* operator[](int i);
00069         inline const T* operator[](int i) const;
00070         inline int dim1() const;
00071         inline int dim2() const;
00072      ~Array2D();
00073 
00074         /* extended interface (not part of the standard) */
00075 
00076 
00077         inline int ref_count();
00078         inline int ref_count_data();
00079         inline int ref_count_dim1();
00080         Array2D subarray(int i0, int i1, int j0, int j1);
00081 
00082 };
00083 
00084 
00085 template <class T>
00086 Array2D<T>::Array2D() : data_(), v_(), m_(0), n_(0) {} 
00087 
00088 template <class T>
00089 Array2D<T>::Array2D(const Array2D<T> &A) : data_(A.data_), v_(A.v_), 
00090         m_(A.m_), n_(A.n_) {}
00091 
00092 
00093 
00094 
00095 template <class T>
00096 Array2D<T>::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n)
00097 {
00098         if (m>0 && n>0)
00099         {
00100                 T* p = &(data_[0]);
00101                 for (int i=0; i<m; i++)
00102                 {
00103                         v_[i] = p;
00104                         p += n;
00105                 }
00106         }
00107 }
00108 
00109 
00110 
00111 template <class T>
00112 Array2D<T>::Array2D(int m, int n, const T &val) : data_(m*n), v_(m), 
00113                                                                                                         m_(m), n_(n) 
00114 {
00115   if (m>0 && n>0)
00116   {
00117         data_ = val;
00118         T* p  = &(data_[0]);
00119         for (int i=0; i<m; i++)
00120         {
00121                         v_[i] = p;
00122                         p += n;
00123         }
00124   }
00125 }
00126 
00127 template <class T>
00128 Array2D<T>::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n)
00129 {
00130   if (m>0 && n>0)
00131   {
00132         T* p = &(data_[0]);
00133         
00134         for (int i=0; i<m; i++)
00135         {
00136                         v_[i] = p;
00137                         p += n;
00138         }
00139   }
00140 }
00141 
00142 
00143 template <class T>
00144 inline T* Array2D<T>::operator[](int i) 
00145 { 
00146 #ifdef TNT_BOUNDS_CHECK
00147         assert(i >= 0);
00148         assert(i < m_);
00149 #endif
00150 
00151 return v_[i]; 
00152 
00153 }
00154 
00155 
00156 template <class T>
00157 inline const T* Array2D<T>::operator[](int i) const
00158 { 
00159 #ifdef TNT_BOUNDS_CHECK
00160         assert(i >= 0);
00161         assert(i < m_);
00162 #endif
00163 
00164 return v_[i]; 
00165 
00166 }
00167 
00168 template <class T>
00169 Array2D<T> & Array2D<T>::operator=(const T &a)
00170 {
00171         /* non-optimzied, but will work with subarrays in future verions */
00172 
00173         for (int i=0; i<m_; i++)
00174                 for (int j=0; j<n_; j++)
00175                 v_[i][j] = a;
00176         return *this;
00177 }
00178 
00179 
00180 
00181 
00182 template <class T>
00183 Array2D<T> Array2D<T>::copy() const
00184 {
00185         Array2D A(m_, n_);
00186 
00187         for (int i=0; i<m_; i++)
00188                 for (int j=0; j<n_; j++)
00189                         A[i][j] = v_[i][j];
00190 
00191 
00192         return A;
00193 }
00194 
00195 
00196 template <class T>
00197 Array2D<T> & Array2D<T>::inject(const Array2D &A)
00198 {
00199         if (A.m_ == m_ &&  A.n_ == n_)
00200         {
00201                 for (int i=0; i<m_; i++)
00202                         for (int j=0; j<n_; j++)
00203                                 v_[i][j] = A[i][j];
00204         }
00205         return *this;
00206 }
00207 
00208 
00209 
00210 
00211 template <class T>
00212 Array2D<T> & Array2D<T>::ref(const Array2D<T> &A)
00213 {
00214         if (this != &A)
00215         {
00216                 v_ = A.v_;
00217                 data_ = A.data_;
00218                 m_ = A.m_;
00219                 n_ = A.n_;
00220                 
00221         }
00222         return *this;
00223 }
00224 
00225 
00226 
00227 template <class T>
00228 Array2D<T> & Array2D<T>::operator=(const Array2D<T> &A)
00229 {
00230         return ref(A);
00231 }
00232 
00233 template <class T>
00234 inline int Array2D<T>::dim1() const { return m_; }
00235 
00236 template <class T>
00237 inline int Array2D<T>::dim2() const { return n_; }
00238 
00239 
00240 template <class T>
00241 Array2D<T>::~Array2D() {}
00242 
00243 
00244 
00245 
00246 template <class T>
00247 inline Array2D<T>::operator T**()
00248 {
00249         return &(v_[0]);
00250 }
00251 template <class T>
00252 inline Array2D<T>::operator const T**()
00253 {
00254         return &(v_[0]);
00255 }
00256 
00257 /* ............... extended interface ............... */
00265 template <class T>
00266 Array2D<T> Array2D<T>::subarray(int i0, int i1, int j0, int j1) 
00267 {
00268         Array2D<T> A;
00269         int m = i1-i0+1;
00270         int n = j1-j0+1;
00271 
00272         /* if either length is zero or negative, this is an invalide
00273                 subarray. return a null view.
00274         */
00275         if (m<1 || n<1)
00276                 return A;
00277 
00278         A.data_ = data_;
00279         A.m_ = m;
00280         A.n_ = n;
00281         A.v_ = Array1D<T*>(m);
00282         T* p = &(data_[0]) + i0 *  n_ + j0;
00283         for (int i=0; i<m; i++)
00284         {
00285                 A.v_[i] = p + i*n_;
00286 
00287         }       
00288         return A;
00289 }
00290 
00291 template <class T>
00292 inline int Array2D<T>::ref_count()
00293 {
00294         return ref_count_data();
00295 }
00296 
00297 
00298 
00299 template <class T>
00300 inline int Array2D<T>::ref_count_data()
00301 {
00302         return data_.ref_count();
00303 }
00304 
00305 template <class T>
00306 inline int Array2D<T>::ref_count_dim1()
00307 {
00308         return v_.ref_count();
00309 }
00310 
00311 
00312 
00313 
00314 } /* namespace TNT */
00315 
00316 #endif
00317 /* TNT_ARRAY2D_H */
00318