00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SPUC_ARRAY1D_H
00023 #define SPUC_ARRAY1D_H
00024
00025 #include <cstdlib>
00026 #include <iostream>
00027
00028 #ifdef SPUC_BOUNDS_CHECK
00029 #include <assert.h>
00030 #endif
00031
00032 namespace SPUC {
00065 template <class T>
00066 class Array1D
00067 {
00068
00069
00070 private:
00071 T* v_;
00072 int n_;
00073 int *ref_count_;
00074
00075 void initialize_(int n);
00076 void copy_(T* p, const T* q, int len) const;
00077 void set_(const T& val);
00078 void destroy_();
00079 inline const T* begin_() const;
00080 inline T* begin_();
00081
00082 public:
00083
00084 typedef T value_type;
00085
00086 Array1D();
00087 explicit Array1D(int n);
00088 Array1D(int n, T *a);
00089 Array1D(int n, const T &a);
00090 inline Array1D(const Array1D &A);
00091 inline Array1D & operator=(const T &a);
00092 inline Array1D & operator=(const Array1D &A);
00093 inline Array1D & ref(const Array1D &A);
00094 Array1D copy() const;
00095 Array1D & inject(const Array1D & A);
00096 inline T& operator[](int i);
00097 inline const T& operator[](int i) const;
00098 inline int dim1() const;
00099 inline int dim() const;
00100 inline int ref_count() const;
00101 ~Array1D();
00102
00103 Array1D<T> mid(int s, int nr) const;
00104 void replace_mid(int s, const Array1D<T>& v) const;
00105 inline int length() const;
00106 Array1D<T>& set_size(int M, bool f) { return(set_size(M)); }
00107 Array1D<T>& newsize(int M, bool f) { return(set_size(M)); }
00108 Array1D<T>& newsize(int M) { return(set_size(M)); }
00109 Array1D<T>& set_size(int M) {
00110 if (dim1() == M) return *this;
00111 destroy_();
00112 initialize_(M);
00113 return *this;
00114 }
00115
00116
00117 };
00123 template <class T>
00124 Array1D<T>::Array1D() : v_(0), n_(0), ref_count_(0)
00125 {
00126 ref_count_ = new int;
00127 *ref_count_ = 1;
00128 }
00129
00136 template <class T>
00137 Array1D<T>::Array1D(const Array1D<T> &A) : v_(A.v_),
00138 n_(A.n_), ref_count_(A.ref_count_)
00139 {
00140 (*ref_count_)++;
00141 }
00142
00143
00144
00156 template <class T>
00157 Array1D<T>::Array1D(int n) : v_(0), n_(n), ref_count_(0)
00158 {
00159 initialize_(n);
00160 ref_count_ = new int;
00161 *ref_count_ = 1;
00162 }
00163
00164
00165
00174 template <class T>
00175 Array1D<T>::Array1D(int n, const T &val) : v_(0), n_(n) ,
00176 ref_count_(0)
00177 {
00178 initialize_(n);
00179 set_(val);
00180 ref_count_ = new int;
00181 *ref_count_ = 1;
00182
00183 }
00184
00194 template <class T>
00195 Array1D<T>::Array1D(int n, T *a) : v_(a), n_(n) ,
00196 ref_count_(0)
00197 {
00198 ref_count_ = new int;
00199 *ref_count_ = 2;
00200
00201 }
00202
00208 template <class T>
00209 inline T& Array1D<T>::operator[](int i)
00210 {
00211 #ifdef SPUC_BOUNDS_CHECK
00212 assert(i>= 0);
00213 assert(i < n_);
00214 #endif
00215 return v_[i];
00216 }
00217
00223 template <class T>
00224 inline const T& Array1D<T>::operator[](int i) const
00225 {
00226 #ifdef SPUC_BOUNDS_CHECK
00227 assert(i>= 0);
00228 assert(i < n_);
00229 #endif
00230 return v_[i];
00231 }
00232
00236 template <class T>
00237 Array1D<T> & Array1D<T>::operator=(const T &a)
00238 {
00239 set_(a);
00240 return *this;
00241 }
00248 template <class T>
00249 Array1D<T> Array1D<T>::copy() const
00250 {
00251 Array1D A( n_);
00252 copy_(A.begin_(), begin_(), n_);
00253
00254 return A;
00255 }
00256
00257
00258
00282 template <class T>
00283 Array1D<T> & Array1D<T>::inject(const Array1D &A)
00284 {
00285 if (A.n_ == n_)
00286 copy_(begin_(), A.begin_(), n_);
00287
00288 return *this;
00289 }
00290
00291
00292
00293
00294
00305 template <class T>
00306 Array1D<T> & Array1D<T>::ref(const Array1D<T> &A)
00307 {
00308 if (this != &A)
00309 {
00310 (*ref_count_) --;
00311 if ( *ref_count_ < 1)
00312 {
00313 destroy_();
00314 }
00315
00316 n_ = A.n_;
00317 v_ = A.v_;
00318 ref_count_ = A.ref_count_;
00319
00320 (*ref_count_) ++ ;
00321
00322 }
00323 return *this;
00324 }
00325
00329 template <class T>
00330 Array1D<T> & Array1D<T>::operator=(const Array1D<T> &A)
00331 {
00332 return ref(A);
00333 }
00334
00339 template <class T>
00340 inline int Array1D<T>::dim1() const { return n_; }
00341
00342 template <class T>
00343 inline int Array1D<T>::length() const { return n_; }
00344
00349 template <class T>
00350 inline int Array1D<T>::dim() const { return n_; }
00351
00352
00353
00358 template <class T>
00359 inline int Array1D<T>::ref_count() const
00360 {
00361 return *ref_count_;
00362 }
00363
00364 template <class T>
00365 Array1D<T>::~Array1D()
00366 {
00367 (*ref_count_) --;
00368
00369 if (*ref_count_ < 1)
00370 destroy_();
00371 }
00372
00373
00374
00375 template <class T>
00376 void Array1D<T>::initialize_(int n)
00377 {
00378
00379
00380 v_ = new T[n];
00381 n_ = n;
00382 }
00383
00384 template <class T>
00385 void Array1D<T>::set_(const T& a)
00386 {
00387 T *begin = &(v_[0]);
00388 T *end = begin+ n_;
00389
00390 for (T* p=begin; p<end; p++)
00391 *p = a;
00392
00393 }
00394
00395 template <class T>
00396 void Array1D<T>::copy_(T* p, const T* q, int len) const
00397 {
00398 T *end = p + len;
00399 while (p<end )
00400 *p++ = *q++;
00401
00402 }
00403
00404 template <class T>
00405 void Array1D<T>::destroy_()
00406 {
00407
00408 if (v_ != 0)
00409 {
00410 delete[] (v_);
00411 }
00412
00413 if (ref_count_ != 0)
00414 delete ref_count_;
00415 }
00416
00420 template <class T>
00421 const T* Array1D<T>::begin_() const { return &(v_[0]); }
00422
00426 template <class T>
00427 T* Array1D<T>::begin_() { return &(v_[0]); }
00428
00429 template <class T>
00430 Array1D<T> Array1D<T>::mid(int s, int nr) const
00431 {
00432 Array1D A( nr );
00433 for (int i=0;i<nr;i++) A[i] = v_[s+i];
00434 return A;
00435 }
00436 template <class T>
00437 void Array1D<T>::replace_mid(int s, const Array1D<T>& v) const
00438 {
00439 for (int i=0;i<v.dim();i++) v_[s+i] = v[i];
00440 }
00441
00442
00443
00444 }
00445
00446 #endif
00447