4 #include "MEDMEM_Exception.hxx"
5 #include "MEDMEM_define.hxx"
6 #include "MEDMEM_PointerOf.hxx"
9 using namespace MED_EN;
12 A template class to generate an array of any particular type (int, long,
13 float, double) for our purpose in the MED++ library./n/n
15 Arrays can be stored in MED_FULL_INTERLACE mode (ie : x1,y1,z1,x2,y2,z2...) or
16 in MED_NO_INTERLACE mode ( x1,x2,..xn, y1, y2 ..,yn,z1,...,zn)./n The alternate
17 representation mode is calculate ONLY when it is usefull. We assure coherency
18 for minor data modifications (element, line or column) if you use set methods.
19 But, if you get a pointer and modify the array, no automatical coherency is possible.
20 You can use calculateOther to force a recalculation and insure the coherency./n
21 No recalculation is done, when the entire array is modified./n
22 Theses arrays are "Med like" arrays; lower bound equals 1. (first element is element 1,
23 first coordinate is coordinate 1). /n
25 Available constructors are :/n
27 - default constructor (not very usefull)/n
28 - constructor asking for array dimensions and mode (does memory allocation for you)/n
29 - constructor asking for array dimensions, mode and values (doesn't do memory allocation
30 but copies pointers only.)/n
31 - a copy constructor which copies only pointers./n
32 (be aware of coherency)
33 - a copy constructor which copies data (deepcopy)./n
34 - assignement operator is also available and only copies pointers (and not data)./n/n
36 Attribute "pointers" aren't standard pointers but class PointerOf objects in order to simplify
39 A simple test program (testUArray) allows to test this class.
42 template <class T> class MEDARRAY
46 /*! leading dimension of value (example : space dimension for coordinates) */
48 /*! length of values (example : number of nodes for coordinates) */
49 med_int _lengthValues;
50 /*! data access mode. possible values are :\n
51 - MED_FULL_INTERLACE (default mode) \n
54 /*! Pointer to representation in mode MED_FULL_INTERLACE */
55 PointerOf <T> _valuesFull;
56 /*! Pointer to representation in mode MED_NO_INTERLACE */
57 PointerOf <T> _valuesNo;
58 /*! Pointer to representation in mode _mode */
59 PointerOf <T> _valuesDefault;
60 /*! Pointer to representation in the other mode (!=_mode) */
61 PointerOf <T> _valuesOther;
68 MEDARRAY (const med_int ld_values, const med_int length_values,
69 const medModeSwitch mode=MED_FULL_INTERLACE);
70 MEDARRAY (T* values, const med_int ld_values,
71 const med_int length_values, const medModeSwitch mode=MED_FULL_INTERLACE);
72 MEDARRAY (MEDARRAY const &m);
73 MEDARRAY (MEDARRAY const &m, bool copyOther);
74 MEDARRAY & operator = (const MEDARRAY & m);
76 inline med_int getLeadingValue() const;
77 inline med_int getLengthValue() const;
79 const T * get (const medModeSwitch mode) ;
80 const T * getRow (const med_int i) ;
81 const T * getColumn (const med_int j) ;
82 const T getIJ (const med_int i, const med_int j) const;
83 // T * const get (const medModeSwitch mode) const;
84 // T * const getRow (const med_int i) const;
85 // T * const getColumn (const med_int j) const;
86 // T const getIJ (const med_int i, const med_int j) const;
88 inline medModeSwitch getMode() const;
90 void set (const medModeSwitch mode,const T* value);
91 void setI (const med_int i, const T* value);
92 void setJ (const med_int j, const T* value);
93 void setIJ (const med_int i, const med_int j, const T value);
95 void calculateOther();
96 bool isOtherCalculated() const {return (const T*)_valuesOther != NULL;}
97 void clearOtherMode();
100 //-------------------------------------------------//
102 // IMPLEMENTED CODE //
104 //-------------------------------------------------//
107 template <class T> inline MEDARRAY<T>::MEDARRAY():
108 _ldValues(0), _lengthValues(0), _mode(MED_FULL_INTERLACE),
109 _valuesFull(), _valuesNo(),
110 _valuesDefault(), _valuesOther()
114 // ------------------
116 template <class T> inline MEDARRAY<T>::~MEDARRAY()
120 // ------------------
122 /*! This constructor does allocation and does not set values : \n.
123 It allocates a "T" array of length_values*ld_values length.\n
124 You don't have to know the T values when calling this construtor
125 but you have to call "set" method to initialize them later.
126 You also can get the pointer to the memory zone (with "get" method),
128 The desallocation of T array is not your responsability. \n\n
129 Throws MEDEXCEPTION if T array length is < 1*/
131 template <class T> MEDARRAY<T>::MEDARRAY(const med_int ld_values,
132 const med_int length_values,
133 const medModeSwitch mode):
135 _ldValues(ld_values),
136 _lengthValues(length_values),
138 _valuesFull(), _valuesNo(),
139 _valuesDefault(),_valuesOther()
141 BEGIN_OF("constructor MEDARRAY<T>::MEDARRAY(const med_int, const med_int, const medModeSwitch)");
143 // if ld_values < 1 or length_values < 1
144 // throws an exception
145 // Pointers are setted to NULL
147 if ((ld_values<1)|(length_values<1))
149 throw MEDEXCEPTION(LOCALIZED("MEDARRAY<T>::MEDARRAY(const med_int, const med_int, const medModeSwitch) : dimension < 1 !"));
152 if ( _mode == MED_FULL_INTERLACE)
154 _valuesFull.set(length_values*ld_values);
155 _valuesDefault.set((T*) _valuesFull);
159 ASSERT (_mode == MED_NO_INTERLACE);
160 _valuesNo.set(length_values*ld_values);
161 _valuesDefault.set((T*)_valuesNo);
164 ASSERT( (T*)_valuesDefault != NULL);
165 SCRUTE((T*)_valuesDefault);
166 SCRUTE((T*)_valuesOther);
167 SCRUTE((T*)_valuesNo);
168 SCRUTE((T*)_valuesFull);
170 END_OF("constructor MEDARRAY<T>::MEDARRAY(const med_int, const med_int, const medModeSwitch ()");
173 // ------------------
175 /*! This constructor duplicate T*values.\n
177 Throws MEDEXCEPTION if the lenght of T is < 1*/
178 template <class T> MEDARRAY<T>::MEDARRAY( T*values,
179 const med_int ld_values,
180 const med_int length_values,
181 const medModeSwitch mode):
182 _ldValues(ld_values),
183 _lengthValues(length_values),
185 _valuesFull(),_valuesNo(),
186 _valuesDefault(),_valuesOther()
188 BEGIN_OF("constructor MEDARRAY<T>::MEDARRAY(T* values, const med_int, const med_int, const medModeSwitch)");
190 // if ld_values < 1 or length_values < 1, we could not allocate
191 // throws an exception
193 if ( (ld_values<1) | (length_values<1) )
195 throw MEDEXCEPTION(LOCALIZED("MEDARRAY<T>::MEDARRAY(T* values, const med_int, const medModeSwitch) : dimension < 1 !"));
197 if ( _mode == MED_FULL_INTERLACE)
199 _valuesFull.set(_ldValues*length_values,values);
200 _valuesDefault.set((T*)_valuesFull);
204 ASSERT (_mode == MED_NO_INTERLACE);
205 _valuesNo.set(_ldValues*length_values,values);
206 _valuesDefault.set((T*)_valuesNo);
209 ASSERT( (T*)_valuesDefault != NULL);
210 SCRUTE((T*)_valuesDefault);
211 SCRUTE((T*)_valuesOther);
212 SCRUTE((T*)_valuesNo);
213 SCRUTE((T*)_valuesFull);
215 END_OF("constructor MEDARRAY<T>::MEDARRAY(T* values, const med_int, const med_int, const medModeSwitch)");
218 // ------------------
220 /*! This constructor allocates a new medarray and does a copy of pointers/n
221 It DOES NOT copy the memory . The two objects will share the same data./n
222 (for copying data, use constructor MEDARRAY(MEDARRAY<T> const & m,bool copyOther). */
223 template <class T> MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m ):
224 _ldValues(m._ldValues),
225 _lengthValues(m._lengthValues),
227 _valuesFull((const T*)m._valuesFull),
228 _valuesNo((const T*)m._valuesNo),
229 _valuesDefault((const T*)m._valuesDefault),
230 _valuesOther((const T*)m._valuesOther)
232 BEGIN_OF("constructor MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m)");
233 ASSERT( (T*)_valuesDefault != NULL);
234 SCRUTE((T*)_valuesDefault);
235 SCRUTE((T*)_valuesOther);
236 SCRUTE((T*)_valuesNo);
237 SCRUTE((T*)_valuesFull);
238 END_OF("constructor MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m)");
241 /*! This constructor allocates a new array and does a copy of values
242 included in the m arrays./n
243 If the boolean is setted to true, both representations (in full mode
244 and no interlace mode) will be copied./n
245 Otherwise, only _valuesDefault will be copied./n
246 Desallocation of the arrays is not your reponsability./n/n
247 Throws MEDEXCEPTION if _valuesOther is null and copyOther equals true*/
248 template <class T> MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & p,bool copyOther ):
249 _ldValues(p._ldValues),
250 _lengthValues(p._lengthValues),
257 BEGIN_OF("Constructeur deepCopy MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m,bool copyOther");
259 // PG : Non, s'il n'y a rien, on test et on ne copie rien, c'est tout !
261 // if ( copyOther==true && ((const T*)p._valuesOther==NULL))
263 // throw MEDEXCEPTION("MEDARRAY MEDARRAY const &m,bool copyOther : No Other values defined and bool = true !");
266 if ( _mode == MED_FULL_INTERLACE)
268 _valuesFull.set(p._ldValues*p._lengthValues,(const T*)p._valuesFull);
269 _valuesDefault.set((T*)_valuesFull);
271 if ((const T*)p._valuesNo != NULL)
273 _valuesNo.set(p._ldValues*p._lengthValues,(const T*)p._valuesNo);
274 _valuesOther.set((T*)_valuesNo);
279 ASSERT (_mode == MED_NO_INTERLACE);
280 _valuesNo.set(p._ldValues*p._lengthValues,(const T*)p._valuesNo);
281 _valuesDefault.set((T*)_valuesNo);
283 if ((const T*)p._valuesFull != NULL)
285 _valuesFull.set(p._ldValues*p._lengthValues,(const T*)p._valuesFull);
286 _valuesOther.set((T*)_valuesFull);
291 // ------------------
293 // /*! This operator does a copy of pointers/n
294 // It DOES NOT copy of the memory.
295 // The two objects will share data./n */
297 template <class T> MEDARRAY<T> & MEDARRAY<T>::operator = (const MEDARRAY & m)
300 BEGIN_OF("Operator = MEDARRAY<T>");
302 _ldValues=m._ldValues;
303 _lengthValues=m._lengthValues;
308 if ((const T*) m._valuesFull !=NULL)
309 _valuesFull.set(_ldValues*_lengthValues,(const T*) m._valuesFull);
311 if ((const T*) m._valuesNo !=NULL)
312 _valuesNo.set(_ldValues*_lengthValues,(const T*) m._valuesNo);
314 if (_mode == MED_FULL_INTERLACE) {
315 //PN : pour enlever les warning compilateur
316 //_valuesDefault.set((const T*) _valuesFull);
317 //_valuesOther.set((const T*) _valuesNo);
318 _valuesDefault.set((T*) _valuesFull);
319 _valuesOther.set((T*) _valuesNo);
321 ASSERT (_mode == MED_NO_INTERLACE);
322 //PN : pour enlever les warning compilateur
323 //_valuesDefault.set((const T*) _valuesNo);
324 //_valuesOther.set((const T*) _valuesFull);
325 _valuesDefault.set((T*) _valuesNo);
326 _valuesOther.set((T*) _valuesFull);
329 SCRUTE((T*)_valuesDefault);
330 SCRUTE((T*)_valuesOther);
331 SCRUTE((T*)_valuesNo);
332 SCRUTE((T*)_valuesFull);
334 END_OF("Operator = MEDARRAY<T>");
338 // ------------------
340 /*! returns _ldValues. (for example, space dimension for coordinates array)*/
341 template <class T> inline med_int MEDARRAY<T>::getLeadingValue() const
346 // ------------------
348 /*! returns _ldValues. (for example, number of nodes for coordinates array)*/
349 template <class T> inline med_int MEDARRAY<T>::getLengthValue() const
351 return _lengthValues;
354 // ------------------
356 /*! returns a pointer to _valuesDefault or _valuesOther, depending on
357 mode value : if mode is the same as _mode, _valuesDefault is returned.
358 else, if _valuesOther is calculated (if necessary) and then returned.
359 The pointer can be used to set values */
360 template <class T> const T* MEDARRAY<T>::get(const medModeSwitch mode)
362 BEGIN_OF("MEDARRAY<T>::get(const medModeSwitch mode)");
363 if ((T*)_valuesDefault == NULL)
365 throw MEDEXCEPTION("MEDARRAY::get(mode) : No values defined !");
369 //PN : pour enlever les warning compilateurs
370 //return (const T*)_valuesDefault;
371 return (T*) _valuesDefault;
375 if ((T*)_valuesOther == NULL)
379 //PN : pour enlever les warning compilateurs
380 //return (const T*)_valuesDefault;
381 return (T*) _valuesOther;
383 END_OF("MEDARRAY<T>::get(const medModeSwitch mode)");
386 // ------------------
388 /*! returns a pointer to ith element of the array.
389 (ith line in a MED_FULL_INTERLACE representation )/n
390 Be aware : if _mode is MED_NO_INTERLACE, the entire
391 array will be recalculate in MED_FULL_INTERLACE representation./n*/
393 template <class T> const T* MEDARRAY<T>::getRow(const med_int i)
396 BEGIN_OF("MEDARRAY<T>::getRow(const med_int i)");
398 if ((T*)_valuesDefault == NULL)
400 throw MEDEXCEPTION("MEDARRAY::getRow(i) : No values defined !");
404 throw MEDEXCEPTION("MEDARRAY::getRow(i) : argument i must be >= 1");
408 throw MEDEXCEPTION("MEDARRAY::getRow(i) : argument i must be <= _lengthValues");
411 if ((T*)_valuesFull == NULL)
413 ASSERT(((T*) _valuesDefault)==((T*) _valuesNo));
416 ASSERT((T*)_valuesFull != NULL);
418 // PN pour enlever les warning compilateurs
419 //const T* ptr = (const T*)_valuesFull + (i-1)*_ldValues;
420 const T* ptr = (T*) _valuesFull + (i-1)*_ldValues;
422 END_OF("MEDARRAY<T>::getRow(const med_int i )");
425 // ------------------
427 /*! this method is similar to getRow method./n
428 It returns a pointer to jth line of the array in a MED_NO-INTERLACE representation
429 (for example, 2nd coordinates)./n
430 Be aware : if _mode is MED_FULL_INTERLACE, the entire
431 array will be recalculate in MED_NO_INTERLACE representation./n*/
433 template <class T> const T* MEDARRAY<T>::getColumn(const med_int j)
435 BEGIN_OF("MEDARRAY<T>::getColumn(const med_int j)");
436 if ((T*)_valuesDefault == NULL)
438 throw MEDEXCEPTION("MEDARRAY::getColumn(j) : No values defined !");
442 throw MEDEXCEPTION("MEDARRAY::getColumn(j) : argument j must be >= 1");
446 throw MEDEXCEPTION("MEDARRAY::getColumn(j) : argument j must be <= _ldValues");
449 if ((T*)_valuesNo == NULL)
451 ASSERT(((T*) _valuesDefault)==((T*) _valuesFull));
454 //PN pour enlever les warning compilateur
455 //const T* ptr = (const T*)_valuesNo + (j-1)*_lengthValues;
456 const T* ptr = ( T*)_valuesNo + (j-1)*_lengthValues;
461 // ------------------
463 /*! returns Jth value of Ith element .\n
464 don't forget first element is element 1 (and not element 0). */
465 template <class T> const T MEDARRAY<T>::getIJ(const med_int i,const med_int j) const
467 BEGIN_OF("MEDARRAY<T>::getIJ(const med_int i, const med_int j)");
470 throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument i must be >= 1");
474 throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument i must be <= _lengthValues");
478 throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument j must be >= 1");
482 throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument j must be <= _ldValues");
485 if ( (const T*)_valuesDefault == NULL)
487 throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : No value in array !");
490 if (_mode == MED_FULL_INTERLACE)
492 return _valuesDefault[(i-1)*_ldValues+j-1];
496 return _valuesDefault[(j-1)*_lengthValues+i-1];
498 END_OF("MEDARRAY<T>::getIJ(const med_int i, const med_int j)");
501 // ------------------
503 /*! returns the default mode (_mode)/n
504 (internal use : needed by write method) */
505 template <class T> inline medModeSwitch MEDARRAY<T>::getMode() const
507 BEGIN_OF("MEDARRAY<T>::getMode()");
508 END_OF("MEDARRAY<T>::getMode()");
512 // ------------------
514 /*! sets T pointer of _valuesDefault (cf class PointerOf) on value.\n
515 no copy of value is done. \n
516 the other representation mode is not recalculate.
517 the corresponding pointers are setted to null */
518 // template <class T> void MEDARRAY<T>::set(const medModeSwitch mode, const T* value)
521 // BEGIN_OF("MEDARRAY<T>::set(mode,value)");
524 // if ( _mode == MED_FULL_INTERLACE)
526 // _valuesFull.set(value);
527 // _valuesDefault.set((T*)_valuesFull);
532 // ASSERT (_mode == MED_NO_INTERLACE);
533 // _valuesNo.set(value);
534 // _valuesDefault.set((T*)_valuesNo);
535 // _valuesFull.set(0);
537 // _valuesOther.set(0);
538 // END_OF("MEDARRAY<T>::set(mode,i,value)");
541 // set with duplication because we don't know were value come and
542 // MEDARRAY must have properties on it !!!!
543 template <class T> void MEDARRAY<T>::set(const medModeSwitch mode, const T* value)
545 BEGIN_OF("MEDARRAY<T>::set(mode,value)");
548 if ( _mode == MED_FULL_INTERLACE)
550 _valuesFull.set(_ldValues*_lengthValues,value);
551 _valuesDefault.set((T*)_valuesFull);
556 ASSERT (_mode == MED_NO_INTERLACE);
557 _valuesNo.set(_ldValues*_lengthValues,value);
558 _valuesDefault.set((T*)_valuesNo);
563 END_OF("MEDARRAY<T>::set(mode,i,value)");
566 /*! This function clears the other mode of representation if it exists
567 * It is usefull for people who needs for optimisation reasons to work directly
568 * on the inside array without using set-functions
570 template <class T> void MEDARRAY<T>::clearOtherMode()
572 if(isOtherCalculated())
574 if ( _mode == MED_FULL_INTERLACE)
583 // ------------------
585 /*! Sets ith element to T* values\n
586 if they both exist, both _valuesFull and _valuesNo arrays will be updated./n
587 Throws exception if i < 1 or i > _lengthValues */
588 template <class T> void MEDARRAY<T>::setI(const med_int i, const T* value)
590 BEGIN_OF("MEDARRAY<T>::setI(i,value)");
592 if ((T*)_valuesDefault == NULL)
594 throw MEDEXCEPTION("MEDARRAY::setI(i,value) : No values defined !");
598 throw MEDEXCEPTION("MEDARRAY::setI(i,value) : argument i must be > 0");
600 if ( i > _lengthValues)
602 throw MEDEXCEPTION("MEDARRAY::setI(i,value) : argument i must be <= _lenghtValues");
605 if ((T*)_valuesFull != NULL)
607 for (int k = 0;k<_ldValues;k++)
609 _valuesFull[k+_ldValues*(i-1)] = value[k];
613 if ((T*)_valuesNo != NULL)
615 for (int k = 0;k<_ldValues;k++)
617 _valuesNo[k*_lengthValues +(i-1)] = value[k];
621 END_OF("MEDARRAY::setI(i,value)");
623 // ------------------
625 /*! Sets ith element to T* values\n
626 if they both exist, both _valuesFull and _valuesNo arrays will be updated./n
627 Throws exception if i < 1 or i > _lengthValues */
628 template <class T> void MEDARRAY<T>::setJ(const med_int j, const T* value)
630 BEGIN_OF("MEDARRAY::setJ(j,value)");
631 if (( T*)_valuesDefault == NULL)
633 throw MEDEXCEPTION("MEDARRAY::setJ(j) : No values defined !");
637 throw MEDEXCEPTION("MEDARRAY::setJ(j) : argument j must be >= 1");
641 throw MEDEXCEPTION("MEDARRAY::setJ(j) : argument j must be <= _ldValues");
643 if ((T*)_valuesFull != NULL)
645 for (int k = 0;k<_lengthValues;k++)
647 _valuesFull[k*_ldValues+(j-1)] = value[k];
651 if ((T*)_valuesNo != NULL)
653 for (int k = 0;k<_lengthValues;k++)
655 _valuesNo[k+_lengthValues*(j-1)] = value[k];
658 END_OF("MEDARRAY::setJ(j,value)");
661 // ------------------
663 /*! Sets value of Jth coordinate of Ith element to T value./n
664 Maintains coherency./n
665 Throws exception if we don't have
666 1<=i<=_lengthValues and 1<=j<=_ldValues */
667 template <class T> void MEDARRAY<T>::setIJ(const med_int i, const med_int j, const T value)
669 // 1<=i<=_lengthValues and 1<=j<=_ldValues
672 throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument i must be >= 1");
674 throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument i must be <= _lengthValues");
677 throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument j must be >= 1");
679 throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument j must be <= _ldValues");
681 if ((T*)_valuesDefault == NULL)
683 throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : No value in array !");
686 if ((T*)_valuesFull != NULL)
688 _valuesFull[j-1+_ldValues*(i-1)] = value;
690 if ((T*)_valuesNo != NULL)
692 _valuesNo[(j-1)*_lengthValues+i-1] = value;
696 /*! Calculates the other mode of representation : MED_FULL_INTERLACE
697 if __mode = MED_NO_INTERLACE and vice versa./n
698 Throws exception if no value are setted */
699 template <class T> void MEDARRAY<T>::calculateOther()
701 BEGIN_OF("MEDARRAY<T>::calculateOther()");
702 if ((T*)_valuesDefault == NULL)
704 throw MEDEXCEPTION("MEDARRAY::calculateOther() : No values defined !");
707 if ((T*)_valuesOther == NULL)
709 _valuesOther.set(_ldValues*_lengthValues);
711 if (_mode == MED_NO_INTERLACE)
713 _valuesFull.set((T*)_valuesOther);
717 ASSERT( _mode==MED_FULL_INTERLACE);
718 _valuesNo.set((T*)_valuesOther);
721 for (int i=0; i<_lengthValues;i++)
723 for (int j=0; j<_ldValues; j++)
725 if (_mode == MED_NO_INTERLACE)
727 _valuesFull[i*_ldValues+j] = _valuesNo[j*_lengthValues+i];
731 _valuesNo[j*_lengthValues+i]=_valuesFull[i*_ldValues+j];
735 END_OF("MEDARRAY<T>::calculateOther()");
738 # endif /* # ifndef __MEDARRAY_H__ */