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
00063 template <class T>
00064 class Array2D
00065 {
00066
00067
00068 private:
00069
00070
00071
00072 Array1D<T> data_;
00073 Array1D<T*> v_;
00074 int m_;
00075 int n_;
00076
00077 public:
00078
00079
00080
00094 typedef T value_type;
00095
00101 Array2D();
00102
00103
00111 Array2D(int m, int n);
00112
00113
00125 Array2D(int m, int n, T *a);
00126
00127
00128
00139 Array2D(int m, int n, const T &val);
00140
00141
00148 inline Array2D(const Array2D &A);
00149
00150
00157 inline operator T**();
00158
00166 inline operator const T**() const;
00167
00168
00174 inline Array2D & operator=(const T &val);
00175
00176
00183 inline Array2D & operator=(const Array2D &A);
00184
00185
00186 inline Array2D & ref(const Array2D &A);
00187 Array2D copy() const;
00188 Array2D & inject(const Array2D & A);
00189 inline T* operator[](int i);
00190 inline const T* operator[](int i) const;
00191 inline int dim1() const;
00192 inline int dim2() const;
00193 ~Array2D();
00194
00195
00196
00197
00198 inline int ref_count();
00199 inline int ref_count_data();
00200 inline int ref_count_dim1();
00201 Array2D subarray(int i0, int i1, int j0, int j1);
00202
00203 };
00204
00205
00217 template <class T>
00218 Array2D<T>::Array2D() : data_(), v_(), m_(0), n_(0) {}
00219
00220
00221 template <class T>
00222 Array2D<T>::Array2D(const Array2D<T> &A) : data_(A.data_), v_(A.v_),
00223 m_(A.m_), n_(A.n_) {}
00224
00225
00226
00227
00228 template <class T>
00229 Array2D<T>::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n)
00230 {
00231 if (m>0 && n>0)
00232 {
00233 T* p = &(data_[0]);
00234 for (int i=0; i<m; i++)
00235 {
00236 v_[i] = p;
00237 p += n;
00238 }
00239 }
00240 }
00241
00242
00243
00244 template <class T>
00245 Array2D<T>::Array2D(int m, int n, const T &val) : data_(m*n), v_(m),
00246 m_(m), n_(n)
00247 {
00248 if (m>0 && n>0)
00249 {
00250 data_ = val;
00251 T* p = &(data_[0]);
00252 for (int i=0; i<m; i++)
00253 {
00254 v_[i] = p;
00255 p += n;
00256 }
00257 }
00258 }
00259
00260 template <class T>
00261 Array2D<T>::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n)
00262 {
00263 if (m>0 && n>0)
00264 {
00265 T* p = &(data_[0]);
00266
00267 for (int i=0; i<m; i++)
00268 {
00269 v_[i] = p;
00270 p += n;
00271 }
00272 }
00273 }
00274
00275
00276 template <class T>
00277 inline T* Array2D<T>::operator[](int i)
00278 {
00279 #ifdef TNT_BOUNDS_CHECK
00280 assert(i >= 0);
00281 assert(i < m_);
00282 #endif
00283
00284 return v_[i];
00285
00286 }
00287
00288
00289 template <class T>
00290 inline const T* Array2D<T>::operator[](int i) const
00291 {
00292 #ifdef TNT_BOUNDS_CHECK
00293 assert(i >= 0);
00294 assert(i < m_);
00295 #endif
00296
00297 return v_[i];
00298
00299 }
00300
00301 template <class T>
00302 Array2D<T> & Array2D<T>::operator=(const T &a)
00303 {
00304
00305
00306 for (int i=0; i<m_; i++)
00307 for (int j=0; j<n_; j++)
00308 v_[i][j] = a;
00309 return *this;
00310 }
00311
00312
00313
00314
00315 template <class T>
00316 Array2D<T> Array2D<T>::copy() const
00317 {
00318 Array2D A(m_, n_);
00319
00320 for (int i=0; i<m_; i++)
00321 for (int j=0; j<n_; j++)
00322 A[i][j] = v_[i][j];
00323
00324
00325 return A;
00326 }
00327
00328
00329 template <class T>
00330 Array2D<T> & Array2D<T>::inject(const Array2D &A)
00331 {
00332 if (A.m_ == m_ && A.n_ == n_)
00333 {
00334 for (int i=0; i<m_; i++)
00335 for (int j=0; j<n_; j++)
00336 v_[i][j] = A[i][j];
00337 }
00338 return *this;
00339 }
00340
00341
00342
00343
00344 template <class T>
00345 Array2D<T> & Array2D<T>::ref(const Array2D<T> &A)
00346 {
00347 if (this != &A)
00348 {
00349 v_ = A.v_;
00350 data_ = A.data_;
00351 m_ = A.m_;
00352 n_ = A.n_;
00353
00354 }
00355 return *this;
00356 }
00357
00358
00359
00360 template <class T>
00361 Array2D<T> & Array2D<T>::operator=(const Array2D<T> &A)
00362 {
00363 return ref(A);
00364 }
00365
00366 template <class T>
00367 inline int Array2D<T>::dim1() const { return m_; }
00368
00369 template <class T>
00370 inline int Array2D<T>::dim2() const { return n_; }
00371
00372
00373 template <class T>
00374 Array2D<T>::~Array2D() {}
00375
00376
00377
00378
00379 template <class T>
00380 inline Array2D<T>::operator T**()
00381 {
00382 return &(v_[0]);
00383 }
00384 template <class T>
00385 inline Array2D<T>::operator const T**() const
00386 {
00387 return &(v_[0]);
00388 }
00389
00390
00398 template <class T>
00399 Array2D<T> Array2D<T>::subarray(int i0, int i1, int j0, int j1)
00400 {
00401 Array2D<T> A;
00402 int m = i1-i0+1;
00403 int n = j1-j0+1;
00404
00405
00406
00407
00408 if (m<1 || n<1)
00409 return A;
00410
00411 A.data_ = data_;
00412 A.m_ = m;
00413 A.n_ = n;
00414 A.v_ = Array1D<T*>(m);
00415 T* p = &(data_[0]) + i0 * n_ + j0;
00416 for (int i=0; i<m; i++)
00417 {
00418 A.v_[i] = p + i*n_;
00419
00420 }
00421 return A;
00422 }
00423
00424 template <class T>
00425 inline int Array2D<T>::ref_count()
00426 {
00427 return ref_count_data();
00428 }
00429
00430
00431
00432 template <class T>
00433 inline int Array2D<T>::ref_count_data()
00434 {
00435 return data_.ref_count();
00436 }
00437
00438 template <class T>
00439 inline int Array2D<T>::ref_count_dim1()
00440 {
00441 return v_.ref_count();
00442 }
00443
00444
00445
00446
00447 }
00448
00449 #endif
00450
00451