00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef TNT_ARRAY2D_H
00023 #define TNT_ARRAY2D_H
00024
00025 #include <cstdlib>
00026 #include <iostream>
00027 #ifdef TNT_BOUNDS_CHECK
00028 #include <assert.h>
00029 #endif
00030
00031 #include "tnt_array1d.h"
00032
00033 namespace TNT
00034 {
00035
00036 template <class T>
00037 class Array2D
00038 {
00039
00040
00041 private:
00042
00043
00044
00045 Array1D<T> data_;
00046 Array1D<T*> v_;
00047 int m_;
00048 int n_;
00049
00050 public:
00051
00052 typedef T value_type;
00053 Array2D();
00054 Array2D(int m, int n);
00055 Array2D(int m, int n, T *a);
00056 Array2D(int m, int n, const T &a);
00057 inline Array2D(const Array2D &A);
00058 inline operator T**();
00059 inline operator const T**();
00060 inline Array2D & operator=(const T &a);
00061 inline Array2D & operator=(const Array2D &A);
00062 inline Array2D & ref(const Array2D &A);
00063 Array2D copy() const;
00064 Array2D & inject(const Array2D & A);
00065 inline T* operator[](int i);
00066 inline const T* operator[](int i) const;
00067 inline int dim1() const;
00068 inline int dim2() const;
00069 ~Array2D();
00070
00071
00072
00073
00074 inline int ref_count();
00075 inline int ref_count_data();
00076 inline int ref_count_dim1();
00077 Array2D subarray(int i0, int i1, int j0, int j1);
00078
00079 };
00080
00081
00082 template <class T>
00083 Array2D<T>::Array2D() : data_(), v_(), m_(0), n_(0) {}
00084
00085 template <class T>
00086 Array2D<T>::Array2D(const Array2D<T> &A) : data_(A.data_), v_(A.v_),
00087 m_(A.m_), n_(A.n_) {}
00088
00089
00090
00091
00092 template <class T>
00093 Array2D<T>::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n)
00094 {
00095 if (m>0 && n>0)
00096 {
00097 T* p = &(data_[0]);
00098 for (int i=0; i<m; i++)
00099 {
00100 v_[i] = p;
00101 p += n;
00102 }
00103 }
00104 }
00105
00106
00107
00108 template <class T>
00109 Array2D<T>::Array2D(int m, int n, const T &val) : data_(m*n), v_(m),
00110 m_(m), n_(n)
00111 {
00112 if (m>0 && n>0)
00113 {
00114 data_ = val;
00115 T* p = &(data_[0]);
00116 for (int i=0; i<m; i++)
00117 {
00118 v_[i] = p;
00119 p += n;
00120 }
00121 }
00122 }
00123
00124 template <class T>
00125 Array2D<T>::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n)
00126 {
00127 if (m>0 && n>0)
00128 {
00129 T* p = &(data_[0]);
00130
00131 for (int i=0; i<m; i++)
00132 {
00133 v_[i] = p;
00134 p += n;
00135 }
00136 }
00137 }
00138
00139
00140 template <class T>
00141 inline T* Array2D<T>::operator[](int i)
00142 {
00143 #ifdef TNT_BOUNDS_CHECK
00144 assert(i >= 0);
00145 assert(i < m_);
00146 #endif
00147
00148 return v_[i];
00149
00150 }
00151
00152
00153 template <class T>
00154 inline const T* Array2D<T>::operator[](int i) const
00155 {
00156 #ifdef TNT_BOUNDS_CHECK
00157 assert(i >= 0);
00158 assert(i < m_);
00159 #endif
00160
00161 return v_[i];
00162
00163 }
00164
00165 template <class T>
00166 Array2D<T> & Array2D<T>::operator=(const T &a)
00167 {
00168
00169
00170 for (int i=0; i<m_; i++)
00171 for (int j=0; j<n_; j++)
00172 v_[i][j] = a;
00173 return *this;
00174 }
00175
00176
00177
00178
00179 template <class T>
00180 Array2D<T> Array2D<T>::copy() const
00181 {
00182 Array2D A(m_, n_);
00183
00184 for (int i=0; i<m_; i++)
00185 for (int j=0; j<n_; j++)
00186 A[i][j] = v_[i][j];
00187
00188
00189 return A;
00190 }
00191
00192
00193 template <class T>
00194 Array2D<T> & Array2D<T>::inject(const Array2D &A)
00195 {
00196 if (A.m_ == m_ && A.n_ == n_)
00197 {
00198 for (int i=0; i<m_; i++)
00199 for (int j=0; j<n_; j++)
00200 v_[i][j] = A[i][j];
00201 }
00202 return *this;
00203 }
00204
00205
00206
00207
00208 template <class T>
00209 Array2D<T> & Array2D<T>::ref(const Array2D<T> &A)
00210 {
00211 if (this != &A)
00212 {
00213 v_ = A.v_;
00214 data_ = A.data_;
00215 m_ = A.m_;
00216 n_ = A.n_;
00217
00218 }
00219 return *this;
00220 }
00221
00222
00223
00224 template <class T>
00225 Array2D<T> & Array2D<T>::operator=(const Array2D<T> &A)
00226 {
00227 return ref(A);
00228 }
00229
00230 template <class T>
00231 inline int Array2D<T>::dim1() const { return m_; }
00232
00233 template <class T>
00234 inline int Array2D<T>::dim2() const { return n_; }
00235
00236
00237 template <class T>
00238 Array2D<T>::~Array2D() {}
00239
00240
00241
00242
00243 template <class T>
00244 inline Array2D<T>::operator T**()
00245 {
00246 return &(v_[0]);
00247 }
00248 template <class T>
00249 inline Array2D<T>::operator const T**()
00250 {
00251 return &(v_[0]);
00252 }
00253
00254
00262 template <class T>
00263 Array2D<T> Array2D<T>::subarray(int i0, int i1, int j0, int j1)
00264 {
00265 Array2D<T> A;
00266 int m = i1-i0+1;
00267 int n = j1-j0+1;
00268
00269
00270
00271
00272 if (m<1 || n<1)
00273 return A;
00274
00275 A.data_ = data_;
00276 A.m_ = m;
00277 A.n_ = n;
00278 A.v_ = Array1D<T*>(m);
00279 T* p = &(data_[0]) + i0 * n_ + j0;
00280 for (int i=0; i<m; i++)
00281 {
00282 A.v_[i] = p + i*n_;
00283
00284 }
00285 return A;
00286 }
00287
00288 template <class T>
00289 inline int Array2D<T>::ref_count()
00290 {
00291 return ref_count_data();
00292 }
00293
00294
00295
00296 template <class T>
00297 inline int Array2D<T>::ref_count_data()
00298 {
00299 return data_.ref_count();
00300 }
00301
00302 template <class T>
00303 inline int Array2D<T>::ref_count_dim1()
00304 {
00305 return v_.ref_count();
00306 }
00307
00308
00309
00310
00311 }
00312
00313 #endif
00314
00315