00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SPUC_ARRAY3D_H
00023 #define SPUC_ARRAY3D_H
00024
00025 #include <cstdlib>
00026 #include <iostream>
00027 #ifdef SPUC_BOUNDS_CHECK
00028 #include <assert.h>
00029 #endif
00030
00031 namespace SPUC {
00067 template <class T>
00068 class Array3D
00069 {
00070
00071
00072 private:
00073 T*** v_;
00074 int m_;
00075 int n_;
00076 int k_;
00077 int *ref_count_;
00078
00079 void initialize_(T* data, int m, int n, int k);
00080 void copy_(T* p, const T* q, int len) const;
00081 void set_(const T& val);
00082 void destroy_();
00083 inline const T* begin_() const;
00084 inline T* begin_();
00085
00086 public:
00087
00088 typedef T value_type;
00089
00090 Array3D();
00091 Array3D(int m, int n, int k);
00092 Array3D(int m, int n, int k, T *a);
00093 Array3D(int m, int n, int k, const T &a);
00094 inline Array3D(const Array3D &A);
00095 inline Array3D & operator=(const T &a);
00096 inline Array3D & operator=(const Array3D &A);
00097 inline Array3D & ref(const Array3D &A);
00098 Array3D copy() const;
00099 Array3D & inject(const Array3D & A);
00100 inline T** operator[](int i);
00101 inline const T* const * operator[](int i) const;
00102 inline int dim1() const;
00103 inline int dim2() const;
00104 inline int dim3() const;
00105 inline int ref_count() const;
00106 ~Array3D();
00107
00108
00109 };
00110
00111
00118 template <class T>
00119 Array3D<T>::Array3D(const Array3D<T> &A) : v_(A.v_), m_(A.m_),
00120 n_(A.n_), k_(A.k_), ref_count_(A.ref_count_)
00121 {
00122 (*ref_count_)++;
00123 }
00124
00125
00126
00139 template <class T>
00140 Array3D<T>::Array3D(int m, int n, int k) : v_(0), m_(m), n_(n), k_(k), ref_count_(0)
00141 {
00142 initialize_(new T[m*n*k], m,n,k);
00143 ref_count_ = new int;
00144 *ref_count_ = 1;
00145 }
00146
00147
00148
00159 template <class T>
00160 Array3D<T>::Array3D(int m, int n, int k, const T &val) : v_(0), m_(m), n_(n) ,
00161 k_(k), ref_count_(0)
00162 {
00163 initialize_(new T[m*n*k], m,n,k);
00164 set_(val);
00165 ref_count_ = new int;
00166 *ref_count_ = 1;
00167
00168 }
00169
00184 template <class T>
00185 Array3D<T>::Array3D(int m, int n, int k, T *a) : v_(0), m_(m), n_(n) ,
00186 k_(k), ref_count_(0)
00187 {
00188 initialize_(a, m, n, k);
00189 ref_count_ = new int;
00190 *ref_count_ = 2;
00191
00192 }
00193
00194
00204 template <class T>
00205 inline T** Array3D<T>::operator[](int i)
00206 {
00207 #ifdef SPUC_BOUNDS_CHECK
00208 assert(i >= 0);
00209 assert(i < m_);
00210 #endif
00211
00212 return v_[i];
00213
00214 }
00215
00216 template <class T>
00217 inline const T* const * Array3D<T>::operator[](int i) const { return v_[i]; }
00218
00222 template <class T>
00223 Array3D<T> & Array3D<T>::operator=(const T &a)
00224 {
00225 set_(a);
00226 return *this;
00227 }
00234 template <class T>
00235 Array3D<T> Array3D<T>::copy() const
00236 {
00237 Array3D A(m_, n_, k_);
00238 copy_(A.begin_(), begin_(), m_*n_*k_);
00239
00240 return A;
00241 }
00242
00243
00267 template <class T>
00268 Array3D<T> & Array3D<T>::inject(const Array3D &A)
00269 {
00270 if (A.m_ == m_ && A.n_ == n_)
00271 copy_(begin_(), A.begin_(), m_*n_);
00272
00273 return *this;
00274 }
00275
00276
00277
00278
00279
00290 template <class T>
00291 Array3D<T> & Array3D<T>::ref(const Array3D<T> &A)
00292 {
00293 if (this != &A)
00294 {
00295 (*ref_count_) --;
00296 if ( *ref_count_ < 1 )
00297 {
00298 destroy_();
00299 }
00300
00301 m_ = A.m_;
00302 n_ = A.n_;
00303 k_ = A.k_;
00304 v_ = A.v_;
00305 ref_count_ = A.ref_count_;
00306
00307 (*ref_count_) ++ ;
00308
00309 }
00310 return *this;
00311 }
00312
00316 template <class T>
00317 Array3D<T> & Array3D<T>::operator=(const Array3D<T> &A)
00318 {
00319 return ref(A);
00320 }
00321
00325 template <class T>
00326 inline int Array3D<T>::dim1() const { return m_; }
00327
00331 template <class T>
00332 inline int Array3D<T>::dim2() const { return n_; }
00333
00337 template <class T>
00338 inline int Array3D<T>::dim3() const { return k_; }
00339
00340
00345 template <class T>
00346 inline int Array3D<T>::ref_count() const
00347 {
00348 return *ref_count_;
00349 }
00350
00351 template <class T>
00352 Array3D<T>::~Array3D()
00353 {
00354 (*ref_count_) --;
00355
00356 if (*ref_count_ < 1)
00357 destroy_();
00358 }
00359
00360
00361
00362 template <class T>
00363 void Array3D<T>::initialize_( T* data, int m, int n, int k)
00364 {
00365
00366 v_ = new T**[m];
00367 v_[0] = new T*[m*n];
00368 v_[0][0] = data;
00369
00370
00371 for (int i=0; i<m; i++)
00372 {
00373 v_[i] = v_[0] + i * n;
00374 for (int j=0; j<n; j++)
00375 v_[i][j] = v_[0][0] + i * (n*k) + j * k;
00376 }
00377
00378 m_ = m;
00379 n_ = n;
00380 k_ = k;
00381 }
00382
00383 template <class T>
00384 void Array3D<T>::set_(const T& a)
00385 {
00386 T *begin = &(v_[0][0][0]);
00387 T *end = begin+ m_*n_*k_;
00388
00389 for (T* p=begin; p<end; p++)
00390 *p = a;
00391
00392 }
00393
00394 template <class T>
00395 void Array3D<T>::copy_(T* p, const T* q, int len) const
00396 {
00397 T *end = p + len;
00398 while (p<end )
00399 *p++ = *q++;
00400
00401 }
00402
00403 template <class T>
00404 void Array3D<T>::destroy_()
00405 {
00406
00407 if (v_ != 0)
00408 {
00409 delete[] (v_[0][0]);
00410 delete[] (v_[0]);
00411 delete[] (v_);
00412 }
00413
00414 if (ref_count_ != 0)
00415 delete ref_count_;
00416 }
00417
00421 template <class T>
00422 const T* Array3D<T>::begin_() const { return &(v_[0][0][0]); }
00423
00427 template <class T>
00428 T* Array3D<T>::begin_() { return &(v_[0][0][0]); }
00429
00433 template <class T>
00434 Array3D<T>::Array3D() : v_(0), m_(0), n_(0)
00435 {
00436 ref_count_ = new int;
00437 *ref_count_ = 1;
00438 }
00439
00440 }
00441
00442 #endif
00443
00444