Blender V2.61 - r43446

tnt_i_refvec.h

Go to the documentation of this file.
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