Blender V2.61 - r43446

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