00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SPUC_ARRAY2D_H
00023 #define SPUC_ARRAY2D_H
00024
00025 #include <cstdlib>
00026 #include <iostream>
00027 #ifdef SPUC_BOUNDS_CHECK
00028 #include <assert.h>
00029 #endif
00030
00031 namespace SPUC
00032 {
00067 template <class T>
00068 class Array2D
00069 {
00070
00071
00072 private:
00073 T** v_;
00074 int m_;
00075 int n_;
00076 int *ref_count_;
00077
00078 void initialize_(int m, int n);
00079 void copy_(T* p, const T* q, int len) const;
00080 void set_(const T& val);
00081 void destroy_();
00082 inline const T* begin_() const;
00083 inline T* begin_();
00084
00085 public:
00086
00087 typedef T value_type;
00088
00089 Array2D();
00090 Array2D(int m, int n);
00091 Array2D(int m, int n, T *a);
00092 Array2D(int m, int n, const T &a);
00093 inline Array2D(const Array2D &A);
00094 inline Array2D & operator=(const T &a);
00095 inline Array2D & operator=(const Array2D &A);
00096 inline Array2D & ref(const Array2D &A);
00097 Array2D copy() const;
00098 Array2D & inject(const Array2D & A);
00099 inline T* operator[](int i);
00100 inline const T* operator[](int i) const;
00101 inline int dim1() const;
00102 inline int dim2() const;
00103 inline int ref_count() const;
00104 ~Array2D();
00105
00106 inline int cols() const;
00107 inline int rows() const;
00108 Array2D<T>& newsize(int M, int N) { return(set_size(M,N)); }
00109 Array2D<T>& set_size(int M, int N) {
00110 if (dim1() == M && dim2() == N)
00111 return *this;
00112 destroy_();
00113 initialize_(M,N);
00114 return *this;
00115 }
00116
00117
00118 };
00119
00120
00127 template <class T>
00128 Array2D<T>::Array2D(const Array2D<T> &A) : v_(A.v_), m_(A.m_),
00129 n_(A.n_), ref_count_(A.ref_count_)
00130 {
00131 (*ref_count_)++;
00132 }
00133
00134
00135
00147 template <class T>
00148 Array2D<T>::Array2D(int m, int n) : v_(0), m_(m), n_(n), ref_count_(0)
00149 {
00150 initialize_(m,n);
00151 ref_count_ = new int;
00152 *ref_count_ = 1;
00153 }
00154
00155
00156
00166 template <class T>
00167 Array2D<T>::Array2D(int m, int n, const T &val) : v_(0), m_(m), n_(n) ,
00168 ref_count_(0)
00169 {
00170 initialize_(m,n);
00171 set_(val);
00172 ref_count_ = new int;
00173 *ref_count_ = 1;
00174
00175 }
00176
00189 template <class T>
00190 Array2D<T>::Array2D(int m, int n, T *a) : v_(0), m_(m), n_(n) ,
00191 ref_count_(0)
00192 {
00193 T* p = a;
00194 v_ = new T*[m];
00195 for (int i=0; i<m; i++)
00196 {
00197 v_[i] = p;
00198 p += n;
00199 }
00200 ref_count_ = new int;
00201 *ref_count_ = 2;
00202
00203 }
00204
00205
00217 template <class T>
00218 inline T* Array2D<T>::operator[](int i)
00219 {
00220 #ifdef SPUC_BOUNDS_CHECK
00221 assert(i >= 0);
00222 assert(i < m_);
00223 #endif
00224
00225 return v_[i];
00226
00227 }
00228
00229 template <class T>
00230 inline const T* Array2D<T>::operator[](int i) const { return v_[i]; }
00231
00235 template <class T>
00236 Array2D<T> & Array2D<T>::operator=(const T &a)
00237 {
00238 set_(a);
00239 return *this;
00240 }
00247 template <class T>
00248 Array2D<T> Array2D<T>::copy() const
00249 {
00250 Array2D A(m_, n_);
00251 copy_(A.begin_(), begin_(), m_*n_);
00252
00253 return A;
00254 }
00255
00256
00280 template <class T>
00281 Array2D<T> & Array2D<T>::inject(const Array2D &A)
00282 {
00283 if (A.m_ == m_ && A.n_ == n_)
00284 copy_(begin_(), A.begin_(), m_*n_);
00285
00286 return *this;
00287 }
00288
00289
00290
00291
00292
00303 template <class T>
00304 Array2D<T> & Array2D<T>::ref(const Array2D<T> &A)
00305 {
00306 if (this != &A)
00307 {
00308 (*ref_count_) --;
00309 if ( *ref_count_ < 1 )
00310 {
00311 destroy_();
00312 }
00313
00314 m_ = A.m_;
00315 n_ = A.n_;
00316 v_ = A.v_;
00317 ref_count_ = A.ref_count_;
00318
00319 (*ref_count_) ++ ;
00320
00321 }
00322 return *this;
00323 }
00324
00328 template <class T>
00329 Array2D<T> & Array2D<T>::operator=(const Array2D<T> &A)
00330 {
00331 return ref(A);
00332 }
00333
00338 template <class T> inline int Array2D<T>::dim1() const { return m_; }
00339 template <class T> inline int Array2D<T>::rows() const { return m_; }
00340
00345 template <class T> inline int Array2D<T>::dim2() const { return n_; }
00346 template <class T> inline int Array2D<T>::cols() const { return n_; }
00347
00348
00353 template <class T>
00354 inline int Array2D<T>::ref_count() const
00355 {
00356 return *ref_count_;
00357 }
00358
00359 template <class T>
00360 Array2D<T>::~Array2D()
00361 {
00362 (*ref_count_) --;
00363
00364 if (*ref_count_ < 1)
00365 destroy_();
00366 }
00367
00368
00369
00370 template <class T>
00371 void Array2D<T>::initialize_(int m, int n)
00372 {
00373
00374
00375 T* p = new T[m*n];
00376 v_ = new T*[m];
00377 for (int i=0; i<m; i++)
00378 {
00379 v_[i] = p;
00380 p+=n;
00381 }
00382 m_ = m;
00383 n_ = n;
00384 }
00385
00386 template <class T>
00387 void Array2D<T>::set_(const T& a)
00388 {
00389 T *begin = &v_[0][0];
00390 T *end = begin+ m_*n_;
00391
00392 for (T* p=begin; p<end; p++)
00393 *p = a;
00394
00395 }
00396
00397 template <class T>
00398 void Array2D<T>::copy_(T* p, const T* q, int len) const
00399 {
00400 T *end = p + len;
00401 while (p<end )
00402 *p++ = *q++;
00403
00404 }
00405
00406 template <class T>
00407 void Array2D<T>::destroy_()
00408 {
00409
00410 if (v_ != 0)
00411 {
00412 delete[] (v_[0]);
00413 delete[] (v_);
00414 }
00415
00416 if (ref_count_ != 0)
00417 delete ref_count_;
00418 }
00419
00423 template <class T>
00424 const T* Array2D<T>::begin_() const { return &(v_[0][0]); }
00425
00429 template <class T>
00430 T* Array2D<T>::begin_() { return &(v_[0][0]); }
00431
00435 template <class T>
00436 Array2D<T>::Array2D() : v_(0), m_(0), n_(0)
00437 {
00438 ref_count_ = new int;
00439 *ref_count_ = 1;
00440 }
00441
00442
00443
00444
00445
00446 }
00447
00448 #endif
00449
00450