Blender V2.61 - r43446
|
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