00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef TNT_I_REFVEC_H
00023 #define TNT_I_REFVEC_H
00024
00025 #include <cstdlib>
00026 #include <iostream>
00027
00028 #ifdef TNT_BOUNDS_CHECK
00029 #include <assert.h>
00030 #endif
00031
00032 #ifndef NULL
00033 #define NULL 0
00034 #endif
00035
00036 namespace TNT
00037 {
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 template <class T>
00055 class i_refvec
00056 {
00057
00058
00059 private:
00060 T* data_;
00061 int *ref_count_;
00062
00063
00064 public:
00065
00066 i_refvec();
00067 explicit i_refvec(int n);
00068 inline i_refvec(T* data);
00069 inline i_refvec(const i_refvec &v);
00070 inline T* begin();
00071 inline const T* begin() const;
00072 inline T& operator[](int i);
00073 inline const T& operator[](int i) const;
00074 inline i_refvec<T> & operator=(const i_refvec<T> &V);
00075 void copy_(T* p, const T* q, const T* e);
00076 void set_(T* p, const T* b, const T* e);
00077 inline int ref_count() const;
00078 inline int is_null() const;
00079 inline void destroy();
00080 ~i_refvec();
00081
00082 };
00083
00084 template <class T>
00085 void i_refvec<T>::copy_(T* p, const T* q, const T* e)
00086 {
00087 for (T* t=p; q<e; t++, q++)
00088 *t= *q;
00089 }
00090
00091 template <class T>
00092 i_refvec<T>::i_refvec() : data_(NULL), ref_count_(NULL) {}
00093
00097 template <class T>
00098 i_refvec<T>::i_refvec(int n) : data_(NULL), ref_count_(NULL)
00099 {
00100 if (n >= 1)
00101 {
00102 #ifdef TNT_DEBUG
00103 std::cout << "new data storage.\n";
00104 #endif
00105 data_ = new T[n];
00106 ref_count_ = new int;
00107 *ref_count_ = 1;
00108 }
00109 }
00110
00111 template <class T>
00112 inline i_refvec<T>::i_refvec(const i_refvec<T> &V): data_(V.data_),
00113 ref_count_(V.ref_count_)
00114 {
00115 if (V.ref_count_ != NULL)
00116 (*(V.ref_count_))++;
00117 }
00118
00119
00120 template <class T>
00121 i_refvec<T>::i_refvec(T* data) : data_(data), ref_count_(NULL) {}
00122
00123 template <class T>
00124 inline T* i_refvec<T>::begin()
00125 {
00126 return data_;
00127 }
00128
00129 template <class T>
00130 inline const T& i_refvec<T>::operator[](int i) const
00131 {
00132 return data_[i];
00133 }
00134
00135 template <class T>
00136 inline T& i_refvec<T>::operator[](int i)
00137 {
00138 return data_[i];
00139 }
00140
00141
00142 template <class T>
00143 inline const T* i_refvec<T>::begin() const
00144 {
00145 return data_;
00146 }
00147
00148
00149
00150 template <class T>
00151 i_refvec<T> & i_refvec<T>::operator=(const i_refvec<T> &V)
00152 {
00153 if (this == &V)
00154 return *this;
00155
00156
00157 if (ref_count_ != NULL)
00158 {
00159 (*ref_count_) --;
00160 if ((*ref_count_) == 0)
00161 destroy();
00162 }
00163
00164 data_ = V.data_;
00165 ref_count_ = V.ref_count_;
00166
00167 if (V.ref_count_ != NULL)
00168 (*(V.ref_count_))++;
00169
00170 return *this;
00171 }
00172
00173 template <class T>
00174 void i_refvec<T>::destroy()
00175 {
00176 if (ref_count_ != NULL)
00177 {
00178 #ifdef TNT_DEBUG
00179 std::cout << "destorying data... \n";
00180 #endif
00181 delete ref_count_;
00182
00183 #ifdef TNT_DEBUG
00184 std::cout << "deleted ref_count_ ...\n";
00185 #endif
00186 if (data_ != NULL)
00187 delete []data_;
00188 #ifdef TNT_DEBUG
00189 std::cout << "deleted data_[] ...\n";
00190 #endif
00191 data_ = NULL;
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 template<class T>
00202 int i_refvec<T>::is_null() const
00203 {
00204 return (data_ == NULL ? 1 : 0);
00205 }
00206
00207
00208
00209
00210
00211
00212
00213 template <class T>
00214 int i_refvec<T>::ref_count() const
00215 {
00216 if (data_ == NULL)
00217 return 0;
00218 else
00219 return (ref_count_ != NULL ? *ref_count_ : -1) ;
00220 }
00221
00222 template <class T>
00223 i_refvec<T>::~i_refvec()
00224 {
00225 if (ref_count_ != NULL)
00226 {
00227 (*ref_count_)--;
00228
00229 if (*ref_count_ == 0)
00230 destroy();
00231 }
00232 }
00233
00234
00235 }
00236
00237
00238
00239
00240
00241 #endif
00242
00243