doxygen: intern/smoke tagged.
[blender.git] / intern / smoke / intern / tnt / tnt_array2d.h
1 /** \file smoke/intern/tnt/tnt_array2d.h
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_ARRAY2D_H
26 #define TNT_ARRAY2D_H
27
28 #include <cstdlib>
29 #include <iostream>
30 #ifdef TNT_BOUNDS_CHECK
31 #include <assert.h>
32 #endif
33
34 #include "tnt_array1d.h"
35
36 namespace TNT
37 {
38
39 template <class T>
40 class Array2D 
41 {
42
43
44   private:
45
46
47
48         Array1D<T> data_;
49         Array1D<T*> v_;
50         int m_;
51     int n_;
52
53   public:
54
55     typedef         T   value_type;
56                Array2D();
57                Array2D(int m, int n);
58                Array2D(int m, int n,  T *a);
59                Array2D(int m, int n, const T &a);
60     inline Array2D(const Array2D &A);
61         inline operator T**();
62         inline operator const T**();
63         inline Array2D & operator=(const T &a);
64         inline Array2D & operator=(const Array2D &A);
65         inline Array2D & ref(const Array2D &A);
66                Array2D copy() const;
67                    Array2D & inject(const Array2D & A);
68         inline T* operator[](int i);
69         inline const T* operator[](int i) const;
70         inline int dim1() const;
71         inline int dim2() const;
72      ~Array2D();
73
74         /* extended interface (not part of the standard) */
75
76
77         inline int ref_count();
78         inline int ref_count_data();
79         inline int ref_count_dim1();
80         Array2D subarray(int i0, int i1, int j0, int j1);
81
82 };
83
84
85 template <class T>
86 Array2D<T>::Array2D() : data_(), v_(), m_(0), n_(0) {} 
87
88 template <class T>
89 Array2D<T>::Array2D(const Array2D<T> &A) : data_(A.data_), v_(A.v_), 
90         m_(A.m_), n_(A.n_) {}
91
92
93
94
95 template <class T>
96 Array2D<T>::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n)
97 {
98         if (m>0 && n>0)
99         {
100                 T* p = &(data_[0]);
101                 for (int i=0; i<m; i++)
102                 {
103                         v_[i] = p;
104                         p += n;
105                 }
106         }
107 }
108
109
110
111 template <class T>
112 Array2D<T>::Array2D(int m, int n, const T &val) : data_(m*n), v_(m), 
113                                                                                                         m_(m), n_(n) 
114 {
115   if (m>0 && n>0)
116   {
117         data_ = val;
118         T* p  = &(data_[0]);
119         for (int i=0; i<m; i++)
120         {
121                         v_[i] = p;
122                         p += n;
123         }
124   }
125 }
126
127 template <class T>
128 Array2D<T>::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n)
129 {
130   if (m>0 && n>0)
131   {
132         T* p = &(data_[0]);
133         
134         for (int i=0; i<m; i++)
135         {
136                         v_[i] = p;
137                         p += n;
138         }
139   }
140 }
141
142
143 template <class T>
144 inline T* Array2D<T>::operator[](int i) 
145
146 #ifdef TNT_BOUNDS_CHECK
147         assert(i >= 0);
148         assert(i < m_);
149 #endif
150
151 return v_[i]; 
152
153 }
154
155
156 template <class T>
157 inline const T* Array2D<T>::operator[](int i) const
158
159 #ifdef TNT_BOUNDS_CHECK
160         assert(i >= 0);
161         assert(i < m_);
162 #endif
163
164 return v_[i]; 
165
166 }
167
168 template <class T>
169 Array2D<T> & Array2D<T>::operator=(const T &a)
170 {
171         /* non-optimzied, but will work with subarrays in future verions */
172
173         for (int i=0; i<m_; i++)
174                 for (int j=0; j<n_; j++)
175                 v_[i][j] = a;
176         return *this;
177 }
178
179
180
181
182 template <class T>
183 Array2D<T> Array2D<T>::copy() const
184 {
185         Array2D A(m_, n_);
186
187         for (int i=0; i<m_; i++)
188                 for (int j=0; j<n_; j++)
189                         A[i][j] = v_[i][j];
190
191
192         return A;
193 }
194
195
196 template <class T>
197 Array2D<T> & Array2D<T>::inject(const Array2D &A)
198 {
199         if (A.m_ == m_ &&  A.n_ == n_)
200         {
201                 for (int i=0; i<m_; i++)
202                         for (int j=0; j<n_; j++)
203                                 v_[i][j] = A[i][j];
204         }
205         return *this;
206 }
207
208
209
210
211 template <class T>
212 Array2D<T> & Array2D<T>::ref(const Array2D<T> &A)
213 {
214         if (this != &A)
215         {
216                 v_ = A.v_;
217                 data_ = A.data_;
218                 m_ = A.m_;
219                 n_ = A.n_;
220                 
221         }
222         return *this;
223 }
224
225
226
227 template <class T>
228 Array2D<T> & Array2D<T>::operator=(const Array2D<T> &A)
229 {
230         return ref(A);
231 }
232
233 template <class T>
234 inline int Array2D<T>::dim1() const { return m_; }
235
236 template <class T>
237 inline int Array2D<T>::dim2() const { return n_; }
238
239
240 template <class T>
241 Array2D<T>::~Array2D() {}
242
243
244
245
246 template <class T>
247 inline Array2D<T>::operator T**()
248 {
249         return &(v_[0]);
250 }
251 template <class T>
252 inline Array2D<T>::operator const T**()
253 {
254         return &(v_[0]);
255 }
256
257 /* ............... extended interface ............... */
258 /**
259         Create a new view to a subarray defined by the boundaries
260         [i0][i0] and [i1][j1].  The size of the subarray is
261         (i1-i0) by (j1-j0).  If either of these lengths are zero
262         or negative, the subarray view is null.
263
264 */
265 template <class T>
266 Array2D<T> Array2D<T>::subarray(int i0, int i1, int j0, int j1) 
267 {
268         Array2D<T> A;
269         int m = i1-i0+1;
270         int n = j1-j0+1;
271
272         /* if either length is zero or negative, this is an invalide
273                 subarray. return a null view.
274         */
275         if (m<1 || n<1)
276                 return A;
277
278         A.data_ = data_;
279         A.m_ = m;
280         A.n_ = n;
281         A.v_ = Array1D<T*>(m);
282         T* p = &(data_[0]) + i0 *  n_ + j0;
283         for (int i=0; i<m; i++)
284         {
285                 A.v_[i] = p + i*n_;
286
287         }       
288         return A;
289 }
290
291 template <class T>
292 inline int Array2D<T>::ref_count()
293 {
294         return ref_count_data();
295 }
296
297
298
299 template <class T>
300 inline int Array2D<T>::ref_count_data()
301 {
302         return data_.ref_count();
303 }
304
305 template <class T>
306 inline int Array2D<T>::ref_count_dim1()
307 {
308         return v_.ref_count();
309 }
310
311
312
313
314 } /* namespace TNT */
315
316 #endif
317 /* TNT_ARRAY2D_H */
318