Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.git] / src / MEDMEM / MEDMEM_Array.hxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #ifndef __MEDARRAY_H__
24 #define __MEDARRAY_H__
25
26 #include "MEDMEM_Exception.hxx"
27 #include "MEDMEM_define.hxx"
28 #include "MEDMEM_PointerOf.hxx"
29 #include "MEDMEM_Utilities.hxx"
30
31 /*!
32   A template class to generate an array of any particular type (int, long,
33   float, double) for our purpose in the MED++ library.\n\n
34
35   Arrays can be stored in MED_FULL_INTERLACE mode (ie : x1,y1,z1,x2,y2,z2...) or
36   in MED_NO_INTERLACE mode ( x1,x2,..xn, y1, y2 ..,yn,z1,...,zn).\n The alternate
37   representation mode is calculate ONLY when it is usefull. We assure coherency
38   for minor data modifications (element, line or column) if you use set methods.
39   But, if you get a pointer and modify the array, no automatical coherency is possible.
40   You can use calculateOther to force a recalculation and insure the coherency.\n
41   No recalculation is done, when the entire array is modified.\n
42   Theses arrays are "Med like" arrays; lower bound equals 1. (first element is element 1,
43   first coordinate is coordinate 1). \n
44
45   Available constructors are :\n
46
47   - default constructor (not very usefull)\n
48   - constructor asking for array dimensions and mode (does memory allocation for you)\n
49   - constructor asking for array dimensions, mode and values (doesn't do memory allocation
50     but copies pointers only.)\n
51   - a copy constructor which copies only pointers.\n
52     (be aware of coherency)
53   - a copy constructor which copies data (deepcopy).\n
54   - assignement operator is also available and only copies pointers (and not data).\n\n
55
56   Attribute "pointers" aren't standard pointers but class PointerOf objects in order to simplify
57   memory management.\n
58
59   A simple test program (testUArray) allows to test this class.
60 */
61
62 namespace MEDMEM {
63 template <class T> class MEDARRAY
64 {
65 private :
66
67                                 /*! leading dimension of value (example : space dimension for coordinates) */
68   int   _ldValues;
69                                 /*! length of values (example : number of nodes for coordinates) */
70   int   _lengthValues;
71                                 /*! data access mode. possible values are :\n
72                                   -  MED_FULL_INTERLACE (default mode) \n
73                                   -  MED_NO_INTERLACE */
74   MED_EN::medModeSwitch _mode;
75                                 /*! Pointer to representation in mode MED_FULL_INTERLACE */
76   PointerOf <T> _valuesFull;
77                                 /*! Pointer to representation in mode MED_NO_INTERLACE */
78   PointerOf <T> _valuesNo;
79                                 /*! Pointer to representation in mode _mode */
80   PointerOf <T> _valuesDefault;
81                                 /*! Pointer to representation in the other mode (!=_mode) */
82   PointerOf <T> _valuesOther;
83
84 public :
85
86   inline  MEDARRAY();
87   inline ~MEDARRAY();
88
89   MEDARRAY  (const int ld_values, const int length_values,
90              const MED_EN::medModeSwitch mode=MED_EN::MED_FULL_INTERLACE);
91   MEDARRAY  (T* values, const int ld_values,
92              const int length_values, const MED_EN::medModeSwitch mode=MED_EN::MED_FULL_INTERLACE,bool shallowCopy=false, bool ownershipOfValues=false);
93   MEDARRAY  (MEDARRAY const &m);
94   MEDARRAY  (MEDARRAY const &m, bool copyOther);
95   MEDARRAY & operator = (const MEDARRAY & m);
96
97   MEDARRAY & shallowCopy(const MEDARRAY & m);
98
99   inline int getLeadingValue() const;
100   inline int getLengthValue()  const;
101
102   const T * get        (const MED_EN::medModeSwitch mode) ;
103   const T * getRow     (const int i) ;
104   const T * getColumn  (const int j) ;
105   const T   getIJ (const int i, const int j) const;
106 //    T * const get        (const MED_EN::medModeSwitch mode) const;
107 //    T * const getRow     (const int i) const;
108 //    T * const getColumn  (const int j) const;
109 //    T   const getIJ (const int i, const int j) const;
110
111   inline MED_EN::medModeSwitch getMode() const;
112
113   void set   (const MED_EN::medModeSwitch mode,const T* value);
114   void setI  (const int i,             const T* value);
115   void setJ  (const int j,             const T* value);
116   void setIJ (const int i, const int j, const T  value);
117
118   void calculateOther();
119   bool isOtherCalculated() const {return (const T*)_valuesOther != NULL;}
120   void clearOtherMode();
121 };
122
123 //-------------------------------------------------//
124 //                                                 //
125 //              IMPLEMENTED CODE                   //
126 //                                                 //
127 //-------------------------------------------------//
128
129
130 template <class T> inline MEDARRAY<T>::MEDARRAY():
131   _ldValues(0), _lengthValues(0), _mode(MED_EN::MED_FULL_INTERLACE),
132   _valuesFull(), _valuesNo(),
133   _valuesDefault(), _valuesOther()
134 {
135 }
136
137 //                              ------------------
138
139 template <class T> inline MEDARRAY<T>::~MEDARRAY()
140 {
141 }
142
143 //                              ------------------
144
145                                 /*! This constructor does allocation and does not set values : \n.
146                                     It allocates a "T" array of length_values*ld_values length.\n
147                                     You don't have to know the T values when calling this construtor
148                                     but you have to call "set" method to initialize them later.
149                                     You also can  get the pointer to the memory zone (with "get" method),
150                                     and work with it.\n
151                                     The desallocation of T array is not your responsability. \n\n
152                                     Throws MEDEXCEPTION if  T array length is < 1*/
153
154 template <class T> MEDARRAY<T>::MEDARRAY(const int ld_values,
155                                          const int length_values,
156                                          const MED_EN::medModeSwitch mode):
157
158                                                 _ldValues(ld_values),
159                                                 _lengthValues(length_values),
160                                                 _mode(mode),
161                                                 _valuesFull(), _valuesNo(),
162                                                 _valuesDefault(),_valuesOther()
163 {
164   //  BEGIN_OF_MED("constructor MEDARRAY<T>::MEDARRAY(const int, const int, const medModeSwitch)");
165
166   // if ld_values < 1 or length_values < 1
167   // throws an exception
168   // Pointers are setted to NULL
169
170   if ((ld_values<1)|(length_values<1))
171   {
172         throw MEDEXCEPTION(LOCALIZED("MEDARRAY<T>::MEDARRAY(const int, const int, const medModeSwitch) : dimension < 1 !"));
173   }
174
175   if ( _mode == MED_EN::MED_FULL_INTERLACE)
176   {
177         _valuesFull.set(length_values*ld_values);
178         _valuesDefault.set((T*) _valuesFull);
179   }
180   else
181   {
182         ASSERT_MED (_mode == MED_EN::MED_NO_INTERLACE);
183         _valuesNo.set(length_values*ld_values);
184         _valuesDefault.set((T*)_valuesNo);
185   }
186
187   ASSERT_MED( (T*)_valuesDefault != NULL);
188 //   SCRUTE_MED((T*)_valuesDefault);
189 //   SCRUTE_MED((T*)_valuesOther);
190 //   SCRUTE_MED((T*)_valuesNo);
191 //   SCRUTE_MED((T*)_valuesFull);
192
193   //  END_OF_MED("constructor MEDARRAY<T>::MEDARRAY(const int, const int, const medModeSwitch ()");
194 }
195
196 //                              ------------------
197
198                                 /*! This constructor duplicate T*values.\n
199
200                                     Throws MEDEXCEPTION if  the lenght of T is < 1*/
201 template <class T> MEDARRAY<T>::MEDARRAY( T*values,
202                                           const int ld_values,
203                                           const int length_values,
204                                           const MED_EN::medModeSwitch mode,
205                                           bool shallowCopy,
206                                           bool ownershipOfValues):
207                                                 _ldValues(ld_values),
208                                                 _lengthValues(length_values),
209                                                 _mode(mode),
210                                                 _valuesFull(),_valuesNo(),
211                                                 _valuesDefault(),_valuesOther()
212 {
213   //  BEGIN_OF_MED("constructor MEDARRAY<T>::MEDARRAY(T* values, const int, const int, const medModeSwitch)");
214
215   // if ld_values < 1 or length_values < 1, we could not allocate
216   // throws an exception
217
218   if ( (ld_values<1) | (length_values<1) )
219   {
220            throw MEDEXCEPTION(LOCALIZED("MEDARRAY<T>::MEDARRAY(T* values, const int, const medModeSwitch) : dimension < 1 !"));
221   }
222   if ( _mode == MED_EN::MED_FULL_INTERLACE)
223   {
224         if(shallowCopy)
225           {
226             if(ownershipOfValues)
227               {
228                 _valuesFull.setShallowAndOwnership((const T*)values);
229             }
230             else
231               {
232                 _valuesFull.set((const T*)values);
233               }
234           }
235         else
236           {
237             _valuesFull.set(_ldValues*length_values,values);
238           }
239         _valuesDefault.set((T*)_valuesFull);
240   }
241   else
242   {
243         ASSERT_MED (_mode == MED_EN::MED_NO_INTERLACE);
244         if(shallowCopy)
245         {
246           if(ownershipOfValues)
247             {
248               _valuesNo.setShallowAndOwnership((const T*)values);
249             }
250           else
251             {
252               _valuesNo.set((const T*)values);
253             }
254         }
255         else
256           _valuesNo.set(_ldValues*length_values,values);
257         _valuesDefault.set((T*)_valuesNo);
258   }
259   ASSERT_MED( (T*)_valuesDefault != NULL);
260 //   SCRUTE_MED((T*)_valuesDefault);
261 //   SCRUTE_MED((T*)_valuesOther);
262 //   SCRUTE_MED((T*)_valuesNo);
263 //   SCRUTE_MED((T*)_valuesFull);
264
265   //  END_OF_MED("constructor MEDARRAY<T>::MEDARRAY(T* values, const int, const int, const medModeSwitch)");
266 }
267
268 //                              ------------------
269
270                                 /*! This constructor allocates a new medarray and does a copy of pointers\n
271                                     It DOES NOT copy the memory . The two objects will share the same data.\n
272                                     (for copying data, use constructor MEDARRAY(MEDARRAY<T> const & m,bool copyOther). */
273 template <class T> MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m ):
274                                         _ldValues(m._ldValues),
275                                         _lengthValues(m._lengthValues),
276                                         _mode(m._mode),
277                                         _valuesFull((const T*)m._valuesFull),
278                                         _valuesNo((const T*)m._valuesNo),
279                                         _valuesDefault((const T*)m._valuesDefault),
280                                         _valuesOther((const T*)m._valuesOther)
281 {
282   //  BEGIN_OF_MED("constructor MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m)");
283   ASSERT_MED( (T*)_valuesDefault != NULL);
284 //   SCRUTE_MED((T*)_valuesDefault);
285 //   SCRUTE_MED((T*)_valuesOther);
286 //   SCRUTE_MED((T*)_valuesNo);
287 //   SCRUTE_MED((T*)_valuesFull);
288   //  END_OF_MED("constructor MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m)");
289 }
290
291                                 /*! This constructor allocates a new array and does a copy of values
292                                     included in the m arrays.\n
293                                     If the boolean is setted to true, both representations (in full mode
294                                     and no interlace mode)  will be copied.\n
295                                     Otherwise, only _valuesDefault will be copied.\n
296                                     Desallocation of the arrays is not your reponsability.\n\n
297                                     Throws MEDEXCEPTION if _valuesOther is null and copyOther equals true*/
298 template <class T> MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & p,bool copyOther ):
299                                         _ldValues(p._ldValues),
300                                         _lengthValues(p._lengthValues),
301                                         _mode(p._mode),
302                                         _valuesFull(),
303                                         _valuesNo(),
304                                         _valuesDefault(),
305                                         _valuesOther()
306 {
307   //  BEGIN_OF_MED("Constructeur deepCopy MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m,bool copyOther");
308
309   // PG : Non, s'il n'y a rien, on test et on ne copie rien, c'est tout !
310
311 //    if ( copyOther==true && ((const T*)p._valuesOther==NULL))
312 //      {
313 //        throw MEDEXCEPTION("MEDARRAY MEDARRAY const &m,bool copyOther : No Other values defined and bool = true !");
314 //      }
315
316   if ( _mode == MED_EN::MED_FULL_INTERLACE)
317     {
318       _valuesFull.set(p._ldValues*p._lengthValues,(const T*)p._valuesFull);
319       _valuesDefault.set((T*)_valuesFull);
320       if (copyOther)
321         if ((const T*)p._valuesNo != NULL)
322           {
323             _valuesNo.set(p._ldValues*p._lengthValues,(const T*)p._valuesNo);
324             _valuesOther.set((T*)_valuesNo);
325           }
326     }
327   else
328     {
329       ASSERT_MED (_mode == MED_EN::MED_NO_INTERLACE);
330       _valuesNo.set(p._ldValues*p._lengthValues,(const T*)p._valuesNo);
331       _valuesDefault.set((T*)_valuesNo);
332       if (copyOther)
333         if ((const T*)p._valuesFull != NULL)
334           {
335             _valuesFull.set(p._ldValues*p._lengthValues,(const T*)p._valuesFull);
336             _valuesOther.set((T*)_valuesFull);
337           }
338     }
339 }
340
341 //                              ------------------
342
343 /*! This operator makes a deep copy of the arrays.\n */
344
345 template <class T> MEDARRAY<T> & MEDARRAY<T>::operator = (const MEDARRAY & m)
346 {
347
348   //  BEGIN_OF_MED("Operator = MEDARRAY<T>");
349
350   _ldValues=m._ldValues;
351   _lengthValues=m._lengthValues;
352   _mode=m._mode;
353
354   //  SCRUTE_MED(_mode);
355
356   if ((const T*) m._valuesFull !=NULL)
357     _valuesFull.set(_ldValues*_lengthValues,(const T*) m._valuesFull);
358
359   if ((const T*) m._valuesNo !=NULL)
360     _valuesNo.set(_ldValues*_lengthValues,(const T*) m._valuesNo);
361
362   if (_mode == MED_EN::MED_FULL_INTERLACE) {
363     //PN : pour enlever les warning compilateur
364     //_valuesDefault.set((const T*) _valuesFull);
365     //_valuesOther.set((const T*) _valuesNo);
366     _valuesDefault.set((T*) _valuesFull);
367     _valuesOther.set((T*) _valuesNo);
368   } else {
369     ASSERT_MED (_mode == MED_EN::MED_NO_INTERLACE);
370     //PN : pour enlever les warning compilateur
371     //_valuesDefault.set((const T*) _valuesNo);
372     //_valuesOther.set((const T*) _valuesFull);
373     _valuesDefault.set((T*) _valuesNo);
374     _valuesOther.set((T*) _valuesFull);
375   }
376
377 //   SCRUTE_MED((T*)_valuesDefault);
378 //   SCRUTE_MED((T*)_valuesOther);
379 //   SCRUTE_MED((T*)_valuesNo);
380 //   SCRUTE_MED((T*)_valuesFull);
381
382   //  END_OF_MED("Operator = MEDARRAY<T>");
383   return *this;
384 }
385
386 /*! Idem operator= but performs only shallow copy (just copy of pointers) of arrays contains in _valuesFull and _valuesNo \n
387  WARNING the MEDARRAY returned HAS THE OWNERSHIP OF THE ARRAY !!!! */
388
389 template <class T> MEDARRAY<T> & MEDARRAY<T>::shallowCopy(const MEDARRAY & m)
390 {
391   _ldValues=m._ldValues;
392   _lengthValues=m._lengthValues;
393   _mode=m._mode;
394   if ((const T*) m._valuesFull !=NULL)
395     _valuesFull.setShallowAndOwnership((const T*) m._valuesFull);
396   if ((const T*) m._valuesNo !=NULL)
397     _valuesNo.setShallowAndOwnership((const T*) m._valuesNo);
398   if (_mode == MED_EN::MED_FULL_INTERLACE) {
399     _valuesDefault.set((T*) _valuesFull);
400     _valuesOther.set((T*) _valuesNo);
401   } else {
402     _valuesDefault.set((T*) _valuesNo);
403     _valuesOther.set((T*) _valuesFull);
404   }
405   return *this;
406 }
407
408 //                              ------------------
409
410                                 /*! returns _ldValues. (for example, space dimension for coordinates array)*/
411 template <class T> inline int MEDARRAY<T>::getLeadingValue() const
412 {
413   return _ldValues;
414 }
415
416 //                              ------------------
417
418                                 /*! returns _ldValues. (for example, number of nodes for coordinates array)*/
419 template <class T> inline int MEDARRAY<T>::getLengthValue() const
420 {
421   return _lengthValues;
422 }
423
424 //                              ------------------
425
426                                 /*! returns a pointer to _valuesDefault or _valuesOther, depending on
427                                     mode value : if mode is the same as _mode, _valuesDefault is returned.
428                                     else, if _valuesOther is calculated (if necessary) and then returned.
429                                     The pointer can be used to set values */
430 template <class T> const T* MEDARRAY<T>::get(const MED_EN::medModeSwitch mode)
431 {
432   //  BEGIN_OF_MED("MEDARRAY<T>::get(const medModeSwitch mode)");
433   if ((T*)_valuesDefault == NULL)
434   {
435         throw MEDEXCEPTION("MEDARRAY::get(mode) : No values defined !");
436   }
437   if (mode == _mode)
438   {
439         //PN : pour enlever les warning compilateurs
440         //return (const T*)_valuesDefault;
441         return  (T*) _valuesDefault;
442   }
443   else
444   {
445         if ((T*)_valuesOther == NULL)
446         {
447                 calculateOther();
448         }
449         //PN : pour enlever les warning compilateurs
450         //return (const T*)_valuesDefault;
451         return  (T*) _valuesOther;
452   }
453 }
454
455 //                              ------------------
456
457                                 /*! returns a pointer to ith element of the array.
458                                     (ith line in a MED_FULL_INTERLACE representation )\n
459                                     Be aware : if _mode is MED_NO_INTERLACE, the entire
460                                     array will be recalculate in MED_FULL_INTERLACE representation.\n*/
461
462 template <class T> const T* MEDARRAY<T>::getRow(const int i)
463 {
464   if ((T*)_valuesDefault == NULL)
465   {
466         throw MEDEXCEPTION("MEDARRAY::getRow(i) : No values defined !");
467   }
468   if (i<1)
469   {
470         throw MEDEXCEPTION("MEDARRAY::getRow(i) : argument i must be >= 1");
471   }
472   if (i>_lengthValues)
473   {
474         throw MEDEXCEPTION("MEDARRAY::getRow(i) : argument i must be <= _lengthValues");
475   }
476
477   if ((T*)_valuesFull == NULL)
478   {
479         calculateOther();
480   }
481   ASSERT_MED((T*)_valuesFull != NULL);
482
483   // PN pour enlever les warning compilateurs
484   //const T* ptr = (const T*)_valuesFull + (i-1)*_ldValues;
485   const T* ptr =  (T*) _valuesFull + (i-1)*_ldValues;
486
487   return ptr;
488 }
489 //                              ------------------
490
491                                 /*! this method is similar to getRow method.\n
492                                     It returns a pointer to jth line of the array in a MED_NO-INTERLACE representation
493                                     (for example, 2nd coordinates).\n
494                                     Be aware : if _mode is MED_FULL_INTERLACE, the entire
495                                     array will be recalculate in MED_NO_INTERLACE representation.\n*/
496
497 template <class T> const T* MEDARRAY<T>::getColumn(const int j)
498 {
499   if ((T*)_valuesDefault == NULL)
500   {
501         throw MEDEXCEPTION("MEDARRAY::getColumn(j) : No values defined !");
502   }
503   if (j<1)
504   {
505         throw MEDEXCEPTION("MEDARRAY::getColumn(j) : argument j must be >= 1");
506   }
507   if (j>_ldValues)
508   {
509         throw MEDEXCEPTION("MEDARRAY::getColumn(j) : argument j must be <= _ldValues");
510   }
511
512   if ((T*)_valuesNo == NULL)
513   {
514         ASSERT_MED(((T*) _valuesDefault)==((T*) _valuesFull));
515         calculateOther();
516   }
517   //PN pour enlever les warning compilateur
518   //const T* ptr = (const T*)_valuesNo + (j-1)*_lengthValues;
519   const T* ptr = ( T*)_valuesNo + (j-1)*_lengthValues;
520
521   return ptr;
522 }
523
524 //                              ------------------
525
526                                 /*! returns Jth value of Ith element .\n
527                                     don't forget first element is element 1 (and not element 0). */
528 template <class T> const T MEDARRAY<T>::getIJ(const int i,const  int j) const
529 {
530
531   if (i<1)
532   {
533         throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument i must be >= 1");
534   }
535   if (i>_lengthValues)
536   {
537         throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument i must be <= _lengthValues");
538   }
539   if (j<1)
540   {
541         throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument j must be >= 1");
542   }
543   if (j>_ldValues)
544   {
545         throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument j must be <= _ldValues");
546   }
547
548   if ( (const T*)_valuesDefault ==  NULL)
549   {
550         throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : No value in array !");
551   }
552
553   if (_mode == MED_EN::MED_FULL_INTERLACE)
554   {
555         return _valuesDefault[(i-1)*_ldValues+j-1];
556   }
557   else
558   {
559         return _valuesDefault[(j-1)*_lengthValues+i-1];
560   }
561
562 }
563
564 //                              ------------------
565
566                                 /*! returns the default mode (_mode)\n
567                                     (internal use : needed by write method) */
568 template <class T> inline MED_EN::medModeSwitch MEDARRAY<T>::getMode() const
569 {
570   return _mode;
571 }
572
573 //                              ------------------
574
575                                 /*! sets T pointer of _valuesDefault (cf class PointerOf) on value.\n
576                                     no copy of value is done. \n
577                                     the other representation mode is not recalculate.
578                                     the corresponding pointers are setted to null */
579 //  template <class T> void MEDARRAY<T>::set(const medModeSwitch mode, const T* value)
580 //  {
581
582 //    BEGIN_OF_MED("MEDARRAY<T>::set(mode,value)");
583
584 //    _mode = mode;
585 //    if ( _mode == MED_FULL_INTERLACE)
586 //    {
587 //      _valuesFull.set(value);
588 //      _valuesDefault.set((T*)_valuesFull);
589 //      _valuesNo.set(0);
590 //    }
591 //    else
592 //    {
593 //      ASSERT_MED (_mode == MED_NO_INTERLACE);
594 //      _valuesNo.set(value);
595 //      _valuesDefault.set((T*)_valuesNo);
596 //      _valuesFull.set(0);
597 //    }
598 //    _valuesOther.set(0);
599 //    END_OF_MED("MEDARRAY<T>::set(mode,i,value)");
600 //  }
601
602 // set with duplication because we don't know were value come and
603 // MEDARRAY must have properties on it !!!!
604 template <class T> void MEDARRAY<T>::set(const MED_EN::medModeSwitch mode, const T* value)
605 {
606   //  BEGIN_OF_MED("MEDARRAY<T>::set(mode,value)");
607
608   _mode = mode;
609   if ( _mode == MED_EN::MED_FULL_INTERLACE)
610     {
611       _valuesFull.set(_ldValues*_lengthValues,value);
612       _valuesDefault.set((T*)_valuesFull);
613       _valuesNo.set(0);
614     }
615   else
616     {
617       ASSERT_MED (_mode == MED_EN::MED_NO_INTERLACE);
618       _valuesNo.set(_ldValues*_lengthValues,value);
619       _valuesDefault.set((T*)_valuesNo);
620       _valuesFull.set(0);
621     }
622   _valuesOther.set(0);
623
624   //  END_OF_MED("MEDARRAY<T>::set(mode,i,value)");
625 }
626
627 /*! This function clears the other mode of representation if it exists
628  *  It is usefull for people who needs for optimisation reasons to work directly
629  *  on the inside array without using set-functions
630  */
631 template <class T> void MEDARRAY<T>::clearOtherMode()
632 {
633     if(isOtherCalculated())
634     {
635         if ( _mode == MED_EN::MED_FULL_INTERLACE)
636             _valuesNo.set(0);
637         else
638             _valuesFull.set(0);
639         _valuesOther.set(0);
640     }
641 }
642
643
644 //                              ------------------
645
646                                         /*! Sets ith element to T* values\n
647                                             if they both exist, both _valuesFull and _valuesNo arrays will be updated.\n
648                                             Throws exception if i < 1 or i > _lengthValues */
649 template <class T> void MEDARRAY<T>::setI(const int i, const T* value)
650 {
651   //  BEGIN_OF_MED("MEDARRAY<T>::setI(i,value)");
652
653   if ((T*)_valuesDefault == NULL)
654   {
655         throw MEDEXCEPTION("MEDARRAY::setI(i,value) : No values defined !");
656   }
657   if (i<=0)
658   {
659       throw MEDEXCEPTION("MEDARRAY::setI(i,value) : argument i must be > 0");
660   }
661   if ( i > _lengthValues)
662   {
663      throw MEDEXCEPTION("MEDARRAY::setI(i,value) : argument i must be <= _lenghtValues");
664   }
665
666   if ((T*)_valuesFull != NULL)
667   {
668    for (int k = 0;k<_ldValues;k++)
669    {
670                 _valuesFull[k+_ldValues*(i-1)] = value[k];
671    }
672   }
673
674   if ((T*)_valuesNo != NULL)
675   {
676    for (int k = 0;k<_ldValues;k++)
677    {
678                 _valuesNo[k*_lengthValues +(i-1)] = value[k];
679    }
680   }
681
682   //  END_OF_MED("MEDARRAY::setI(i,value)");
683 }
684 //                              ------------------
685
686                                         /*! Sets ith element to T* values\n
687                                             if they both exist, both _valuesFull and _valuesNo arrays will be updated.\n
688                                             Throws exception if i < 1 or i > _lengthValues */
689 template <class T> void MEDARRAY<T>::setJ(const int j, const T* value)
690 {
691   //  BEGIN_OF_MED("MEDARRAY::setJ(j,value)");
692   if (( T*)_valuesDefault == NULL)
693   {
694         throw MEDEXCEPTION("MEDARRAY::setJ(j) : No values defined !");
695   }
696   if (j<1)
697   {
698         throw MEDEXCEPTION("MEDARRAY::setJ(j) : argument j must be >= 1");
699   }
700   if (j>_ldValues)
701   {
702         throw MEDEXCEPTION("MEDARRAY::setJ(j) : argument j must be <= _ldValues");
703   }
704   if ((T*)_valuesFull != NULL)
705   {
706    for (int k = 0;k<_lengthValues;k++)
707    {
708                 _valuesFull[k*_ldValues+(j-1)] = value[k];
709    }
710   }
711
712   if ((T*)_valuesNo != NULL)
713   {
714    for (int k = 0;k<_lengthValues;k++)
715    {
716                 _valuesNo[k+_lengthValues*(j-1)] = value[k];
717    }
718   }
719   //  END_OF_MED("MEDARRAY::setJ(j,value)");
720 }
721
722 //                              ------------------
723
724                                         /*! Sets value of Jth coordinate of Ith element to T value.\n
725                                             Maintains coherency.\n
726                                             Throws exception if we don't have
727                                             1<=i<=_lengthValues and 1<=j<=_ldValues */
728 template <class T> void MEDARRAY<T>::setIJ(const int i, const int j, const T value)
729 {
730   // 1<=i<=_lengthValues and 1<=j<=_ldValues
731
732   if (i<1)
733     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument i must be >= 1");
734   if (i>_lengthValues)
735     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument i must be <= _lengthValues");
736
737   if (j<1)
738     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument j must be >= 1");
739   if (j>_ldValues)
740     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument j must be <= _ldValues");
741
742   if ((T*)_valuesDefault == NULL)
743   {
744     throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : No value in array !");
745   }
746
747   if ((T*)_valuesFull != NULL)
748   {
749         _valuesFull[j-1+_ldValues*(i-1)] = value;
750   }
751   if ((T*)_valuesNo != NULL)
752   {
753         _valuesNo[(j-1)*_lengthValues+i-1] = value;
754   }
755 }
756
757                                         /*! Calculates the other mode of representation : MED_FULL_INTERLACE
758                                             if __mode = MED_NO_INTERLACE and vice versa.\n
759                                             Throws exception if no value are setted */
760 template <class T> void MEDARRAY<T>::calculateOther()
761 {
762   //  BEGIN_OF_MED("MEDARRAY<T>::calculateOther()");
763   if ((T*)_valuesDefault == NULL)
764   {
765         throw MEDEXCEPTION("MEDARRAY::calculateOther() : No values defined !");
766   }
767
768   if ((T*)_valuesOther == NULL)
769   {
770         _valuesOther.set(_ldValues*_lengthValues);
771   }
772   if (_mode == MED_EN::MED_NO_INTERLACE)
773   {
774         _valuesFull.set((T*)_valuesOther);
775   }
776   else
777   {
778         ASSERT_MED( _mode==MED_EN::MED_FULL_INTERLACE);
779         _valuesNo.set((T*)_valuesOther);
780   }
781
782   for (int i=0; i<_lengthValues;i++)
783   {
784         for (int j=0; j<_ldValues; j++)
785         {
786                 if (_mode == MED_EN::MED_NO_INTERLACE)
787                 {
788                         _valuesFull[i*_ldValues+j] = _valuesNo[j*_lengthValues+i];
789                 }
790                 else
791                 {
792                         _valuesNo[j*_lengthValues+i]=_valuesFull[i*_ldValues+j];
793                 }
794         }
795   }
796   //  END_OF_MED("MEDARRAY<T>::calculateOther()");
797 }
798
799 } //End of namespace MEDMEM
800
801 # endif         /* # ifndef __MEDARRAY_H__ */