doxygen: add newline after \file
[blender.git] / intern / smoke / intern / tnt / tnt_i_refvec.h
1 /** \file
2  * \ingroup smoke
3  */
4 /*
5 *
6 * Template Numerical Toolkit (TNT)
7 *
8 * Mathematical and Computational Sciences Division
9 * National Institute of Technology,
10 * Gaithersburg, MD USA
11 *
12 *
13 * This software was developed at the National Institute of Standards and
14 * Technology (NIST) by employees of the Federal Government in the course
15 * of their official duties. Pursuant to title 17 Section 105 of the
16 * United States Code, this software is not subject to copyright protection
17 * and is in the public domain. NIST assumes no responsibility whatsoever for
18 * its use by other parties, and makes no guarantees, expressed or implied,
19 * about its quality, reliability, or any other characteristic.
20 *
21 */
22
23
24
25 #ifndef TNT_I_REFVEC_H
26 #define TNT_I_REFVEC_H
27
28 #include <cstdlib>
29 #include <iostream>
30
31 #ifdef TNT_BOUNDS_CHECK
32 #include <assert.h>
33 #endif
34
35 #ifndef NULL
36 #define NULL 0
37 #endif
38
39 namespace TNT
40 {
41 /*
42         Internal representation of ref-counted array.  The TNT
43         arrays all use this building block.
44
45         <p>
46         If an array block is created by TNT, then every time 
47         an assignment is made, the left-hand-side reference 
48         is decreased by one, and the right-hand-side refernce
49         count is increased by one.  If the array block was
50         external to TNT, the refernce count is a NULL pointer
51         regardless of how many references are made, since the 
52         memory is not freed by TNT.
53
54
55         
56 */
57 template <class T>
58 class i_refvec
59 {
60
61
62   private:
63     T* data_;                  
64     int *ref_count_;
65
66
67   public:
68
69                          i_refvec();
70         explicit i_refvec(int n);
71         inline   i_refvec(T* data);
72         inline   i_refvec(const i_refvec &v);
73         inline   T*              begin();
74         inline const T* begin() const;
75         inline  T& operator[](int i);
76         inline const T& operator[](int i) const;
77         inline  i_refvec<T> & operator=(const i_refvec<T> &V);
78                     void copy_(T* p, const T* q, const T* e); 
79                     void set_(T* p, const T* b, const T* e); 
80         inline  int      ref_count() const;
81         inline  int is_null() const;
82         inline  void destroy();
83                          ~i_refvec();
84                         
85 };
86
87 template <class T>
88 void i_refvec<T>::copy_(T* p, const T* q, const T* e)
89 {
90         for (T* t=p; q<e; t++, q++)
91                 *t= *q;
92 }
93
94 template <class T>
95 i_refvec<T>::i_refvec() : data_(NULL), ref_count_(NULL) {}
96
97 /**
98         In case n is 0 or negative, it does NOT call new. 
99 */
100 template <class T>
101 i_refvec<T>::i_refvec(int n) : data_(NULL), ref_count_(NULL)
102 {
103         if (n >= 1)
104         {
105 #ifdef TNT_DEBUG
106                 std::cout  << "new data storage.\n";
107 #endif
108                 data_ = new T[n];
109                 ref_count_ = new int;
110                 *ref_count_ = 1;
111         }
112 }
113
114 template <class T>
115 inline   i_refvec<T>::i_refvec(const i_refvec<T> &V): data_(V.data_),
116         ref_count_(V.ref_count_)
117 {
118         if (V.ref_count_ != NULL)
119             (*(V.ref_count_))++;
120 }
121
122
123 template <class T>
124 i_refvec<T>::i_refvec(T* data) : data_(data), ref_count_(NULL) {}
125
126 template <class T>
127 inline T* i_refvec<T>::begin()
128 {
129         return data_;
130 }
131
132 template <class T>
133 inline const T& i_refvec<T>::operator[](int i) const
134 {
135         return data_[i];
136 }
137
138 template <class T>
139 inline T& i_refvec<T>::operator[](int i)
140 {
141         return data_[i];
142 }
143
144
145 template <class T>
146 inline const T* i_refvec<T>::begin() const
147 {
148         return data_;
149 }
150
151
152
153 template <class T>
154 i_refvec<T> & i_refvec<T>::operator=(const i_refvec<T> &V)
155 {
156         if (this == &V)
157                 return *this;
158
159
160         if (ref_count_ != NULL)
161         {
162                 (*ref_count_) --;
163                 if ((*ref_count_) == 0)
164                         destroy();
165         }
166
167         data_ = V.data_;
168         ref_count_ = V.ref_count_;
169
170         if (V.ref_count_ != NULL)
171             (*(V.ref_count_))++;
172
173         return *this;
174 }
175
176 template <class T>
177 void i_refvec<T>::destroy()
178 {
179         if (ref_count_ != NULL)
180         {
181 #ifdef TNT_DEBUG
182                 std::cout << "destorying data... \n";
183 #endif
184                 delete ref_count_;
185
186 #ifdef TNT_DEBUG
187                 std::cout << "deleted ref_count_ ...\n";
188 #endif
189                 if (data_ != NULL)
190                         delete []data_;
191 #ifdef TNT_DEBUG
192                 std::cout << "deleted data_[] ...\n";
193 #endif
194                 data_ = NULL;
195         }
196 }
197
198 /*
199 * return 1 is vector is empty, 0 otherwise
200 *
201 * if is_null() is false and ref_count() is 0, then
202
203 */
204 template<class T>
205 int i_refvec<T>::is_null() const
206 {
207         return (data_ == NULL ? 1 : 0);
208 }
209
210 /*
211 *  returns -1 if data is external, 
212 *  returns 0 if a is NULL array,
213 *  otherwise returns the positive number of vectors sharing
214 *               this data space.
215 */
216 template <class T>
217 int i_refvec<T>::ref_count() const
218 {
219         if (data_ == NULL)
220                 return 0;
221         else
222                 return (ref_count_ != NULL ? *ref_count_ : -1) ; 
223 }
224
225 template <class T>
226 i_refvec<T>::~i_refvec()
227 {
228         if (ref_count_ != NULL)
229         {
230                 (*ref_count_)--;
231
232                 if (*ref_count_ == 0)
233                 destroy();
234         }
235 }
236
237
238 } /* namespace TNT */
239
240
241
242
243
244 #endif
245 /* TNT_I_REFVEC_H */
246