Salome HOME
NRI : Update 1.1a and New organisation.
[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 "MEDMEM_PointerOf.hxx"
7 #include "utilities.h"
8
9 using namespace MED_EN;
10
11 /*!
12   A template class to generate an array of any particular type (int, long,
13   float, double) for our purpose in the MED++ library.
14 */
15
16 template <class T> class MEDARRAY 
17 // Class Template MEDARRAY
18 // template to generate an array of any
19 // particular type (int, long, float, double)
20 // for our purpose in the MED++ library
21 {
22 private :
23   med_int _ldValues;              // leading dimension of value (example : space dimension with coordinates)
24   med_int _lengthValues;          // length of values (example : number of nodes with coordinates) 
25   medModeSwitch _mode;            // data access mode:
26                                   // MED_FULL_INTERLACE (default mode) 
27                                   // or MED_NO_INTERLACE
28   PointerOf <T> _valuesDefault;   // in _mode representation
29   PointerOf <T> _valuesOther;     // in other _mode representation
30
31 public :
32   MEDARRAY(): _ldValues(0), _lengthValues(0), _mode(MED_FULL_INTERLACE),
33               _valuesDefault(), _valuesOther()
34   {
35   };
36
37   ~MEDARRAY()
38   {
39   };
40   
41
42   // the following constructor are for the generation
43   // with the default or not _mode
44
45   MEDARRAY(const med_int ld_values, const med_int length_values, 
46            const medModeSwitch mode=MED_FULL_INTERLACE) ;
47
48   MEDARRAY( T*values, const med_int ld_values,
49            const med_int length_values, const medModeSwitch mode=MED_FULL_INTERLACE) ;
50
51   MEDARRAY(MEDARRAY const &m );
52
53   inline med_int getLeadingValue() const; // as Space Dimension with coordinates
54   inline med_int getLengthValue()  const; // as Number of Nodes with coordinates
55  
56   T * const get   (const medModeSwitch mode) ;
57   T * const getI  (const medModeSwitch mode, const med_int i) ;
58   T   const getIJ (const med_int i,          const 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):
79                                                 _ldValues(ld_values),
80                                                 _lengthValues(length_values),
81                                                 _mode(mode),
82                                                 _valuesOther(),
83                                                 _valuesDefault(length_values*ld_values)
84 {
85   BEGIN_OF("constructor MEDARRAY<T>::MEDARRAY(const med_int, const med_int, const medModeSwitch(= MED_FULL_INTERLACE))");
86
87   // if could not allocate 
88
89   if ((ld_values<1)|(length_values<1))
90   {
91     throw MEDEXCEPTION(LOCALIZED("MEDARRAY<T>::MEDARRAY(const med_int, const med_int, const medModeSwitch) : dimension < 1 !"));
92   }
93
94   SCRUTE((T*)_valuesDefault);
95   SCRUTE((T*)_valuesOther);
96   SCRUTE(_ldValues);
97   SCRUTE(_lengthValues);
98   SCRUTE(_mode);
99
100   END_OF("constructor MEDARRAY<T>::MEDARRAY(const med_int, const med_int, const medModeSwitch (= MED_FULL_INTERLACE))");
101 }
102
103 template <class T> MEDARRAY<T>::MEDARRAY( T*values,
104                                           const med_int ld_values,
105                                           const med_int length_values,
106                                           const medModeSwitch mode): 
107                                                 _ldValues(ld_values),
108                                                 _lengthValues(length_values),
109                                                 _mode(mode),
110                                                 _valuesOther()
111 {
112         _valuesDefault.set(values);
113 }
114
115 template <class T> MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m ):
116                         _ldValues(m._ldValues), 
117                         _lengthValues(m._lengthValues),
118                         _mode(m._mode), 
119                         _valuesDefault((int)m._ldValues*m._lengthValues)
120 {
121   if ( m._ldValues*m._lengthValues >= 0 )
122   {
123         memcpy((T*)_valuesDefault,(const T* const)m._valuesDefault,m._ldValues*m._lengthValues*sizeof(T));
124   }
125   if ((const T* const)(m._valuesOther) != NULL) 
126   {
127       _valuesOther.set(m._ldValues*m._lengthValues);
128       memcpy((T*)_valuesOther,(const T* const)m._valuesOther,m._ldValues*m._lengthValues*sizeof(T));
129   }
130   else
131   {
132         _valuesOther.set(0);
133   }
134 }
135
136 template <class T> inline med_int MEDARRAY<T>::getLeadingValue() const 
137 {
138   return _ldValues ;
139 };
140
141 template <class T> inline med_int MEDARRAY<T>::getLengthValue() const
142 {
143   return _lengthValues ;
144 };
145
146 template <class T> T* const MEDARRAY<T>::get(const medModeSwitch mode) 
147 {
148   if ((T*)_valuesDefault != NULL)
149     if (mode == _mode) 
150       {
151         return _valuesDefault;
152       }
153     else 
154       {
155         calculateOther() ;
156         return _valuesOther ;
157       }
158   throw MEDEXCEPTION("MEDARRAY::get(mode) : No values defined !");
159 }
160
161 template <class T> T* const MEDARRAY<T>::getI(const medModeSwitch mode,const med_int i) 
162 {
163   // 1<=i<=_lengthValues and return an array of _ldValues length
164   // if MED_FULL_INTERLACE
165   // 1<=i<=_ldValues and return an array of _lengthValues length
166   // if MED_NO_INTERLACE
167
168   if (i<=0) 
169       throw MEDEXCEPTION("MEDARRAY::getI(mode,i) : argument i must be > 0");
170
171   if (( T* )_valuesDefault != NULL) 
172   {
173     // if mode = MED_FULL_INTERLACE :
174     int first = _ldValues ;
175     int second = _lengthValues;
176
177     // else :
178     if (mode == MED_NO_INTERLACE) 
179     {
180       first = _lengthValues ;
181       second = _ldValues ;
182     }
183
184     if (i>second) 
185       throw MEDEXCEPTION("MEDARRAY::getI(mode,i) : argument i must be <= second");
186
187     if (mode == _mode)
188       return _valuesDefault + (i-1)*first ;
189     else 
190     {
191       calculateOther() ;
192       return _valuesOther + (i-1)*first ;
193     }
194   }
195   throw MEDEXCEPTION("MEDARRAY::getI(mode,i) : No values defined !");
196 }
197
198
199 template <class T> T const MEDARRAY<T>::getIJ(const med_int i,const  med_int j) const
200 {
201   // 1<=i<=_lengthValues and 1<j<_ldValues
202
203   if (i<1) 
204     throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument i must be >= 1");
205   if (i>_lengthValues) 
206     throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument i must be <= _lengthValues");
207
208   if (j<1) 
209     throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument j must be >= 1");
210   if (j>_ldValues) 
211     throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument j must be <= _ldValues");
212
213   if ( (const T* const)_valuesDefault !=  NULL) 
214   {
215     switch (_mode)
216     {
217         case MED_FULL_INTERLACE :
218         {
219              return _valuesDefault[(i-1)*_ldValues+j-1];
220         }
221         case MED_NO_INTERLACE : 
222         {
223              return _valuesDefault[(j-1)*_lengthValues+i-1];
224         }
225     }
226   } 
227   else
228         throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : No value in array !");
229 }
230
231 template <class T> inline medModeSwitch MEDARRAY<T>::getMode() const 
232 {
233   return _mode ;
234 }
235
236 template <class T> void MEDARRAY<T>::set(medModeSwitch mode, T* value)
237 {
238
239   BEGIN_OF("MEDARRAY<T>::set(mode,i,value)");
240
241   SCRUTE(_ldValues);
242   SCRUTE(_lengthValues);
243   SCRUTE((T*)_valuesDefault);
244   SCRUTE((T*)_valuesOther);
245   SCRUTE(_mode);
246   SCRUTE(mode);
247   SCRUTE(value);
248
249   if ((T*)_valuesDefault != NULL) 
250   {
251       if (mode == _mode)
252       {
253         _valuesDefault = value ;
254         if ((T*)_valuesOther != NULL) calculateOther() ;
255       }
256       else
257       {
258         allocateOther() ;
259         _valuesOther = value ;
260         updateDefault() ;
261       }
262    }
263    else 
264    {
265         throw MEDEXCEPTION("MEDARRAY::set(mode,value) : No values defined !");
266    }
267
268    END_OF("MEDARRAY<T>::set(mode,i,value)");
269 }
270
271 template <class T> void MEDARRAY<T>::setI(medModeSwitch mode, med_int i, T* value)
272 {
273   BEGIN_OF("MEDARRAY<T>::setI(mode,i,value)");
274
275   SCRUTE(i);
276   SCRUTE(_ldValues);
277   SCRUTE(_lengthValues);
278   SCRUTE((T*)_valuesDefault);
279   SCRUTE((T*)_valuesOther);
280   SCRUTE(_mode);
281   SCRUTE(mode);
282
283   // 1<=i<=_lengthValues and return an array of _ldValues length
284   // if MED_FULL_INTERLACE
285   // 1<=i<=_ldValues and return an array of _lengthValues length
286   // if MED_NO_INTERLACE
287
288   if (i<=0) 
289   {
290       throw MEDEXCEPTION("MEDARRAY::setI(mode,i,value) : argument i must be > 0");
291   }
292   if ((T*)_valuesDefault != NULL) 
293   {
294     int first  = _ldValues;
295     int second = _lengthValues;
296
297     if (mode == MED_NO_INTERLACE) 
298     {
299         first  = _lengthValues;
300         second = _ldValues;
301     }
302     SCRUTE(second);
303
304     if ( i > second) 
305     {
306       SCRUTE(i);
307       SCRUTE(second);
308       throw MEDEXCEPTION("MEDARRAY::setI(mode,i,value) : argument i must be <= second");
309     }
310     if (mode == _mode)
311     {
312         for (int k =0;k<first;k++)
313           {
314                 (_valuesDefault + (i-1)*first)[k] = value[k];
315           }
316         if ((T*)_valuesOther != NULL)
317           for (int k =0;k<first;k++) 
318           {
319                 _valuesOther[k*second+i-1] = value[k];
320           }
321     }
322     else
323     {
324         allocateOther() ;
325         //      return _valuesOther + (i-1)*first = &value ;
326         for (int k =0;k<second;k++) 
327         {
328           _valuesOther[(i-1)*first+k-1] = value[k];
329           _valuesDefault[k*second+i-1]  = value[k];
330         }
331     }
332   }
333   else 
334   {
335         throw MEDEXCEPTION("MEDARRAY::setI(mode,i,value) : No values defined !");
336   }
337
338   SCRUTE((T*) _valuesDefault);
339   SCRUTE((T*) _valuesOther);
340
341   END_OF("MEDARRAY::setI(mode,i,value)");
342 }
343
344 template <class T> void MEDARRAY<T>::setIJ(med_int i, med_int j, T value)
345 {
346   // 1<=i<=_lengthValues and 1<=j<=_ldValues
347
348   if (i<1) 
349     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument i must be >= 1");
350   if (i>_lengthValues) 
351     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument i must be <= _lengthValues");
352
353   if (j<1) 
354     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument j must be >= 1");
355   if (j>_ldValues) 
356     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument j must be <= _ldValues");
357
358   if ((T*)_valuesDefault != NULL) 
359   {
360     switch (_mode)
361     {
362       case MED_FULL_INTERLACE :
363       {
364           _valuesDefault[(i-1)*_ldValues+j-1] = value;
365           break;
366       }
367       case MED_NO_INTERLACE : 
368       {
369           _valuesDefault[(j-1)*_lengthValues+i-1] = value;
370           break;
371       }
372     }
373   } 
374   else
375   {
376     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : No value in array !");
377    }
378 }
379
380 template <class T> void MEDARRAY<T>::calculateOther()
381 {
382   BEGIN_OF("MEDARRAY<T>::calculateOther()") ;
383   SCRUTE((T*)_valuesDefault);
384   SCRUTE((T*)_valuesOther);
385   if ((T*)_valuesDefault != NULL) 
386   {
387         //we allocate _valuesOther if needed
388         if ((T*)_valuesOther == NULL) 
389         {
390                 _valuesOther.set(_ldValues*_lengthValues);
391         }
392
393         // we set _valuesOther
394         int first = _ldValues ;
395         int second = _lengthValues;
396         if (_mode == MED_NO_INTERLACE) 
397         {
398                 first = _lengthValues ;
399                 second = _ldValues;
400         }
401         for (int i=0; i<first;i++)
402                 for (int j=0; j<second; j++)
403                         _valuesOther[i*second+j] = _valuesDefault[j*first+i];
404   }
405   else
406   {
407         throw MEDEXCEPTION("MEDARRAY::calculateOther() : No values defined !");
408   }
409   END_OF("MEDARRAY<T>::calculateOther()") ;
410 }
411
412 template <class T> void MEDARRAY<T>::allocateOther()
413 {
414   if ((T*)_valuesDefault != NULL) 
415   {
416     if ((T*)_valuesOther == NULL) 
417     {
418         // we set _valuesOther
419         _valuesOther.set(_ldValues*_lengthValues);
420     }
421   }
422   else
423     throw MEDEXCEPTION("MEDARRAY::allocateOther() : No values defined !");
424 }
425
426 template <class T> void MEDARRAY<T>::updateDefault()
427 {
428   BEGIN_OF("MEDARRAY<T>::updateDefault()");
429
430   if ((T*)_valuesDefault != NULL) 
431   {
432     if ((T*)_valuesOther != NULL) 
433     {
434       // we update _valuesDefault with _valuesOther
435       // if mode = MED_FULL_INTERLACE :
436       int first = _ldValues ;
437       int second = _lengthValues;
438       // else :
439       if (_mode == MED_NO_INTERLACE) 
440       {
441         first = _lengthValues ;
442         second = _ldValues;
443       }
444       for (int i=0; i<first;i++)
445         for (int j=0; j<second; j++)
446           _valuesDefault[j*first+i] = _valuesOther[i*second+j];
447     }
448     else
449     {
450       throw MEDEXCEPTION("MEDARRAY<T>::updateDefault() : No valuesOther defined !");
451     }
452   }
453   else
454   {
455     throw MEDEXCEPTION("MEDARRAY<T>::updateDefault() : No values defined !");
456   }
457
458   END_OF("MEDARRAY<T>::updateDefault()");
459 }
460
461 # endif         /* # ifndef __MEDARRAY_H__ */