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