Blender V2.61 - r43446
|
00001 00004 /* 00005 * 00006 * Template Numerical Toolkit (TNT) 00007 * 00008 * Mathematical and Computational Sciences Division 00009 * National Institute of Technology, 00010 * Gaithersburg, MD USA 00011 * 00012 * 00013 * This software was developed at the National Institute of Standards and 00014 * Technology (NIST) by employees of the Federal Government in the course 00015 * of their official duties. Pursuant to title 17 Section 105 of the 00016 * United States Code, this software is not subject to copyright protection 00017 * and is in the public domain. NIST assumes no responsibility whatsoever for 00018 * its use by other parties, and makes no guarantees, expressed or implied, 00019 * about its quality, reliability, or any other characteristic. 00020 * 00021 */ 00022 00023 00024 00025 #ifndef TNT_I_REFVEC_H 00026 #define TNT_I_REFVEC_H 00027 00028 #include <cstdlib> 00029 #include <iostream> 00030 00031 #ifdef TNT_BOUNDS_CHECK 00032 #include <assert.h> 00033 #endif 00034 00035 #ifndef NULL 00036 #define NULL 0 00037 #endif 00038 00039 namespace TNT 00040 { 00041 /* 00042 Internal representation of ref-counted array. The TNT 00043 arrays all use this building block. 00044 00045 <p> 00046 If an array block is created by TNT, then every time 00047 an assignment is made, the left-hand-side reference 00048 is decreased by one, and the right-hand-side refernce 00049 count is increased by one. If the array block was 00050 external to TNT, the refernce count is a NULL pointer 00051 regardless of how many references are made, since the 00052 memory is not freed by TNT. 00053 00054 00055 00056 */ 00057 template <class T> 00058 class i_refvec 00059 { 00060 00061 00062 private: 00063 T* data_; 00064 int *ref_count_; 00065 00066 00067 public: 00068 00069 i_refvec(); 00070 explicit i_refvec(int n); 00071 inline i_refvec(T* data); 00072 inline i_refvec(const i_refvec &v); 00073 inline T* begin(); 00074 inline const T* begin() const; 00075 inline T& operator[](int i); 00076 inline const T& operator[](int i) const; 00077 inline i_refvec<T> & operator=(const i_refvec<T> &V); 00078 void copy_(T* p, const T* q, const T* e); 00079 void set_(T* p, const T* b, const T* e); 00080 inline int ref_count() const; 00081 inline int is_null() const; 00082 inline void destroy(); 00083 ~i_refvec(); 00084 00085 }; 00086 00087 template <class T> 00088 void i_refvec<T>::copy_(T* p, const T* q, const T* e) 00089 { 00090 for (T* t=p; q<e; t++, q++) 00091 *t= *q; 00092 } 00093 00094 template <class T> 00095 i_refvec<T>::i_refvec() : data_(NULL), ref_count_(NULL) {} 00096 00100 template <class T> 00101 i_refvec<T>::i_refvec(int n) : data_(NULL), ref_count_(NULL) 00102 { 00103 if (n >= 1) 00104 { 00105 #ifdef TNT_DEBUG 00106 std::cout << "new data storage.\n"; 00107 #endif 00108 data_ = new T[n]; 00109 ref_count_ = new int; 00110 *ref_count_ = 1; 00111 } 00112 } 00113 00114 template <class T> 00115 inline i_refvec<T>::i_refvec(const i_refvec<T> &V): data_(V.data_), 00116 ref_count_(V.ref_count_) 00117 { 00118 if (V.ref_count_ != NULL) 00119 (*(V.ref_count_))++; 00120 } 00121 00122 00123 template <class T> 00124 i_refvec<T>::i_refvec(T* data) : data_(data), ref_count_(NULL) {} 00125 00126 template <class T> 00127 inline T* i_refvec<T>::begin() 00128 { 00129 return data_; 00130 } 00131 00132 template <class T> 00133 inline const T& i_refvec<T>::operator[](int i) const 00134 { 00135 return data_[i]; 00136 } 00137 00138 template <class T> 00139 inline T& i_refvec<T>::operator[](int i) 00140 { 00141 return data_[i]; 00142 } 00143 00144 00145 template <class T> 00146 inline const T* i_refvec<T>::begin() const 00147 { 00148 return data_; 00149 } 00150 00151 00152 00153 template <class T> 00154 i_refvec<T> & i_refvec<T>::operator=(const i_refvec<T> &V) 00155 { 00156 if (this == &V) 00157 return *this; 00158 00159 00160 if (ref_count_ != NULL) 00161 { 00162 (*ref_count_) --; 00163 if ((*ref_count_) == 0) 00164 destroy(); 00165 } 00166 00167 data_ = V.data_; 00168 ref_count_ = V.ref_count_; 00169 00170 if (V.ref_count_ != NULL) 00171 (*(V.ref_count_))++; 00172 00173 return *this; 00174 } 00175 00176 template <class T> 00177 void i_refvec<T>::destroy() 00178 { 00179 if (ref_count_ != NULL) 00180 { 00181 #ifdef TNT_DEBUG 00182 std::cout << "destorying data... \n"; 00183 #endif 00184 delete ref_count_; 00185 00186 #ifdef TNT_DEBUG 00187 std::cout << "deleted ref_count_ ...\n"; 00188 #endif 00189 if (data_ != NULL) 00190 delete []data_; 00191 #ifdef TNT_DEBUG 00192 std::cout << "deleted data_[] ...\n"; 00193 #endif 00194 data_ = NULL; 00195 } 00196 } 00197 00198 /* 00199 * return 1 is vector is empty, 0 otherwise 00200 * 00201 * if is_null() is false and ref_count() is 0, then 00202 * 00203 */ 00204 template<class T> 00205 int i_refvec<T>::is_null() const 00206 { 00207 return (data_ == NULL ? 1 : 0); 00208 } 00209 00210 /* 00211 * returns -1 if data is external, 00212 * returns 0 if a is NULL array, 00213 * otherwise returns the positive number of vectors sharing 00214 * this data space. 00215 */ 00216 template <class T> 00217 int i_refvec<T>::ref_count() const 00218 { 00219 if (data_ == NULL) 00220 return 0; 00221 else 00222 return (ref_count_ != NULL ? *ref_count_ : -1) ; 00223 } 00224 00225 template <class T> 00226 i_refvec<T>::~i_refvec() 00227 { 00228 if (ref_count_ != NULL) 00229 { 00230 (*ref_count_)--; 00231 00232 if (*ref_count_ == 0) 00233 destroy(); 00234 } 00235 } 00236 00237 00238 } /* namespace TNT */ 00239 00240 00241 00242 00243 00244 #endif 00245 /* TNT_I_REFVEC_H */ 00246