Salome HOME
Version ok de MED avec MEDGUI.
[modules/med.git] / src / MEDMEM / MEDMEM_Array.hxx
1 #ifndef __MEDARRAY_H__
2 #define __MEDARRAY_H__
3
4 #include "MEDMEM_Exception.hxx"
5 #include "MEDMEM_define.hxx"
6 #include "utilities.h"
7
8 using namespace MED_EN;
9
10 /*!
11   A template class to generate an array of any particular type (int, long,
12   float, double) for our purpose in the MED++ library.
13 */
14
15 template <class T> class MEDARRAY 
16 // Class Template MEDARRAY
17 // template to generate an array of any
18 // particular type (int, long, float, double)
19 // for our purpose in the MED++ library
20 {
21 private :
22   med_int _ld_values ;      // leading dimension of value (example : space dimension with coordinates)
23   med_int _length_values ;  // length of values (example : number of nodes with coordinates) 
24   medModeSwitch _mode;    // data access mode:
25                             // MED_FULL_INTERLACE (default mode) 
26                             // or MED_NO_INTERLACE
27   T * _valuesDefault ;       // in _mode representation
28   T * _valuesOther   ;       // in other _mode
29
30 public :
31   MEDARRAY():_ld_values(0),_length_values(0),_mode(MED_FULL_INTERLACE),_valuesDefault((T*)NULL),_valuesOther((T*)NULL)
32   {
33   };
34
35   ~MEDARRAY()
36   {
37     if (_valuesDefault)
38       delete [] _valuesDefault ;
39     if (_valuesOther)
40       delete [] _valuesOther ;
41   };
42   
43
44   // the following constructor are for the generation
45   // with the default or not _mode
46
47   MEDARRAY(const med_int ld_values, const med_int length_values, 
48            const medModeSwitch mode=MED_FULL_INTERLACE) ;
49
50   MEDARRAY( T*values, const med_int ld_values,
51            const med_int length_values, const medModeSwitch mode=MED_FULL_INTERLACE) ;
52
53   inline med_int getLeadingValue() ; // as Space Dimension with coordinates
54   inline med_int getLengthValue() ; // as Number of Nodes with coordinates
55  
56   T * const get(medModeSwitch mode) ;
57   T* const getI(medModeSwitch mode,med_int i) ;
58   T  getIJ(med_int i, med_int j) const ;
59
60   // need by write, to get default mode !
61   inline medModeSwitch getMode() const ;
62   
63   void set(medModeSwitch mode, T* value);
64   void setI(medModeSwitch mode, med_int i, T* value);
65   void setIJ(med_int i, med_int j, T value);
66
67 private:
68   void calculateOther() ;
69   void allocateOther();
70   void updateDefault();
71 };
72
73
74 // implemented code
75
76 template <class T> MEDARRAY<T>::MEDARRAY(const med_int ld_values,
77                                          const med_int length_values,
78                                          const medModeSwitch mode = MED_FULL_INTERLACE): _ld_values(ld_values),_length_values(length_values),_mode(mode),_valuesOther((T*)NULL)
79 {
80   BEGIN_OF("constructor MEDARRAY<T>::MEDARRAY(const med_int , const med_int, const medModeSwitch (= MED_FULL_INTERLACE))");
81
82   // if could not allocate ?
83   if ((ld_values<1)|(length_values<1))
84     throw MEDEXCEPTION( LOCALIZED("MEDARRAY<T>::MEDARRAY(const med_int, const med_int, const medModeSwitch) : dimension < 1 !"));
85   _valuesDefault = new T[ld_values*length_values] ;
86
87   SCRUTE(_valuesDefault);
88
89   SCRUTE(_valuesOther);
90
91   SCRUTE(_ld_values);
92
93   SCRUTE(_length_values);
94
95   SCRUTE(_mode);
96
97   END_OF("constructor MEDARRAY<T>::MEDARRAY(const med_int , const med_int, const medModeSwitch (= MED_FULL_INTERLACE))");
98 }
99
100 template <class T> MEDARRAY<T>::MEDARRAY( T*values,
101                                           const med_int ld_values,
102                                           const med_int length_values,
103                                           const medModeSwitch mode=MED_FULL_INTERLACE): _ld_values(ld_values),_length_values(length_values),_mode(mode),_valuesOther((T*)NULL)
104 {
105   _valuesDefault = values;
106 }
107
108 template <class T> inline med_int MEDARRAY<T>::getLeadingValue() {
109   return _ld_values ;
110 };
111 template <class T> inline med_int MEDARRAY<T>::getLengthValue() {
112   return _length_values ;
113 };
114
115 template <class T> T* const MEDARRAY<T>::get(medModeSwitch mode) 
116 {
117   if (_valuesDefault != NULL)
118     if (mode == _mode) {
119       return _valuesDefault;
120     }
121     else {
122       calculateOther() ;
123       return _valuesOther ;
124     }
125   throw MEDEXCEPTION("MEDARRAY::get(mode) : No values defined !");
126 }
127
128 template <class T> T* const MEDARRAY<T>::getI(medModeSwitch mode,med_int i)
129 {
130   // 1<=i<=_length_values and return an array of _ld_values length
131   // if MED_FULL_INTERLACE
132   // 1<=i<=_ld_values and return an array of _length_values length
133   // if MED_NO_INTERLACE
134
135   if (_valuesDefault != NULL) {
136     // if mode = MED_FULL_INTERLACE :
137     int first = _ld_values ;
138     int second = _length_values;
139     // else :
140     if (mode == MED_NO_INTERLACE) {
141       first = _length_values ;
142       second = _ld_values ;
143     }
144     if (i<=0) 
145       throw MEDEXCEPTION("MEDARRAY::getI(mode,i) : argument i must be > 0");
146     if (i>second) 
147       throw MEDEXCEPTION("MEDARRAY::getI(mode,i) : argument i must be <= second");
148     if (mode == _mode)
149       return _valuesDefault + (i-1)*first ;
150     else {
151       calculateOther() ;
152       return _valuesOther + (i-1)*first ;
153       //      return _valuesOther + (i-1)*second ;
154     }
155   }
156   throw MEDEXCEPTION("MEDARRAY::getI(mode,i) : No values defined !");
157 }
158
159
160 template <class T> T MEDARRAY<T>::getIJ(med_int i, med_int j) const
161 {
162   // 1<=i<=_length_values and 1<j<_ld_values
163
164   if (i<1) 
165     throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument i must be >= 1");
166   if (i>_length_values) 
167     throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument i must be <= _length_values");
168
169   if (j<1) 
170     throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument j must be >= 1");
171   if (j>_ld_values) 
172     throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument j must be <= _ld_values");
173
174   if (_valuesDefault != NULL) {
175     switch (_mode)
176       {
177       case MED_FULL_INTERLACE :
178         {
179           return _valuesDefault[(i-1)*_ld_values+j-1];
180         }
181       case MED_NO_INTERLACE : 
182         {
183           return _valuesDefault[(j-1)*_length_values+i-1];
184         }
185       }
186   } else
187     throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : No value in array !");
188 }
189
190 template <class T> inline medModeSwitch MEDARRAY<T>::getMode() const 
191 {
192   return _mode ;
193 }
194
195 template <class T> void MEDARRAY<T>::set(medModeSwitch mode, T* value)
196 {
197
198   BEGIN_OF("MEDARRAY<T>::set(mode,i,value)");
199
200   _mode = mode ;
201
202   SCRUTE(_ld_values);
203   SCRUTE(_length_values);
204   SCRUTE(_valuesDefault);
205   SCRUTE(_valuesOther);
206   SCRUTE(_mode);
207   SCRUTE(mode);
208   SCRUTE(value);
209
210   if (_valuesDefault != NULL)
211     if (mode == _mode) {
212       _valuesDefault = value ;
213       if (_valuesOther != NULL) calculateOther() ;
214       //      if (_valuesOther != NULL) _valuesOther = value;
215     }
216     else {
217       allocateOther() ;
218       _valuesOther = value ;
219       updateDefault() ;
220     }
221   else throw MEDEXCEPTION("MEDARRAY::set(mode,value) : No values defined !");
222
223   END_OF("MEDARRAY<T>::set(mode,i,value)");
224 }
225
226 template <class T> void MEDARRAY<T>::setI(medModeSwitch mode, med_int i, T* value)
227 {
228   BEGIN_OF("MEDARRAY<T>::setI(mode,i,value)");
229
230   _mode = mode ;
231
232   SCRUTE(i);
233   SCRUTE(_ld_values);
234   SCRUTE(_length_values);
235   SCRUTE(_valuesDefault);
236   SCRUTE(_valuesOther);
237   SCRUTE(_mode);
238   SCRUTE(mode);
239
240   // 1<=i<=_length_values and return an array of _ld_values length
241   // if MED_FULL_INTERLACE
242   // 1<=i<=_ld_values and return an array of _length_values length
243   // if MED_NO_INTERLACE
244
245   if (_valuesDefault != NULL) {
246     // if mode = MED_FULL_INTERLACE :
247     int first = _ld_values ;
248     int second = _length_values;
249     // else :
250     if (mode == MED_NO_INTERLACE) {
251       first = _length_values ;
252       second = _ld_values ;
253     }
254     SCRUTE(second);
255     if (i<=0) 
256       throw MEDEXCEPTION("MEDARRAY::setI(mode,i,value) : argument i must be > 0");
257     if (i>second) {
258       SCRUTE(i);
259       SCRUTE(second);
260       throw MEDEXCEPTION("MEDARRAY::setI(mode,i,value) : argument i must be <= second");}
261     if (mode == _mode)
262       {
263         //      _valuesDefault + (i-1)*first = value ;
264         for (int k =0;k<first;k++)
265           //      _valuesDefault[(i-1)*second+k] = value[k];
266           (_valuesDefault + (i-1)*first)[k] = value[k];
267         if (_valuesOther != NULL)
268           for (int k =0;k<first;k++) {
269             _valuesOther[k*second+i-1] = value[k];
270           }
271       }
272     else
273       {
274         allocateOther() ;
275         //      return _valuesOther + (i-1)*first = &value ;
276         for (int k =0;k<second;k++) {
277           _valuesOther[(i-1)*first+k-1] = value[k];
278           _valuesDefault[k*second+i-1] = value[k];
279         }
280       }
281   }
282   else throw MEDEXCEPTION("MEDARRAY::setI(mode,i,value) : No values defined !");
283
284   SCRUTE(_valuesDefault);
285   SCRUTE( _valuesOther);
286
287   END_OF("MEDARRAY::setI(mode,i,value)");
288 }
289
290 template <class T> void MEDARRAY<T>::setIJ(med_int i, med_int j, T value)
291 {
292   // 1<=i<=_length_values and 1<j<_ld_values
293
294   if (i<1) 
295     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument i must be >= 1");
296   if (i>_length_values) 
297     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument i must be <= _length_values");
298
299   if (j<1) 
300     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument j must be >= 1");
301   if (j>_ld_values) 
302     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument j must be <= _ld_values");
303
304   if (_valuesDefault != NULL) {
305     switch (_mode)
306       {
307       case MED_FULL_INTERLACE :
308         {
309           _valuesDefault[(i-1)*_ld_values+j-1] = value;
310           break;
311         }
312       case MED_NO_INTERLACE : 
313         {
314           _valuesDefault[(j-1)*_length_values+i-1] = value;
315           break;
316         }
317       }
318   } else
319     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : No value in array !");
320 }
321
322 template <class T> void MEDARRAY<T>::calculateOther()
323 {
324   if (_valuesDefault != NULL) {
325     //we allocate _valuesOther if needed
326     if (_valuesOther == NULL) _valuesOther = new T[_ld_values*_length_values] ;
327     // we set _valuesOther
328     // if mode = MED_FULL_INTERLACE :
329     int first = _ld_values ;
330     int second = _length_values;
331     // else :
332     if (_mode == MED_NO_INTERLACE) {
333       first = _length_values ;
334       second = _ld_values;
335     }
336
337     for (int i=0; i<first;i++)
338       for (int j=0; j<second; j++)
339         _valuesOther[i*second+j] = _valuesDefault[j*first+i];
340   }
341   else
342     throw MEDEXCEPTION("MEDARRAY::calculateOther() : No values defined !");
343 }
344
345 template <class T> void MEDARRAY<T>::allocateOther()
346 {
347   if (_valuesDefault != NULL) {
348     if (_valuesOther == NULL) {
349       // we set _valuesOther
350       _valuesOther = new T[_ld_values*_length_values] ;
351     }
352   }
353   else
354     throw MEDEXCEPTION("MEDARRAY::allocateOther() : No values defined !");
355 }
356
357 template <class T> void MEDARRAY<T>::updateDefault()
358 {
359   BEGIN_OF("MEDARRAY<T>::updateDefault()");
360
361   if (_valuesDefault != NULL) {
362     if (_valuesOther != NULL) {
363       // we update _valuesDefault with _valuesOther
364       // if mode = MED_FULL_INTERLACE :
365       int first = _ld_values ;
366       int second = _length_values;
367       // else :
368       if (_mode == MED_NO_INTERLACE) {
369         first = _length_values ;
370         second = _ld_values;
371       }
372       for (int i=0; i<first;i++)
373         for (int j=0; j<second; j++)
374           _valuesDefault[j*first+i] = _valuesOther[i*second+j];
375     }
376     else
377       throw MEDEXCEPTION("MEDARRAY<T>::updateDefault() : No valuesOther defined !");
378   }
379   else
380     throw MEDEXCEPTION("MEDARRAY<T>::updateDefault() : No values defined !");
381
382   END_OF("MEDARRAY<T>::updateDefault()");
383 }
384
385 # endif         /* # ifndef __MEDARRAY_H__ */