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