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.
43 template <class T> class MEDARRAY
47 /*! leading dimension of value (example : space dimension for coordinates) */
49 /*! length of values (example : number of nodes for coordinates) */
50 med_int _lengthValues;
51 /*! data access mode. possible values are :\n
52 - MED_FULL_INTERLACE (default mode) \n
55 /*! Pointer to representation in mode MED_FULL_INTERLACE */
56 PointerOf <T> _valuesFull;
57 /*! Pointer to representation in mode MED_NO_INTERLACE */
58 PointerOf <T> _valuesNo;
59 /*! Pointer to representation in mode _mode */
60 PointerOf <T> _valuesDefault;
61 /*! Pointer to representation in the other mode (!=_mode) */
62 PointerOf <T> _valuesOther;
69 MEDARRAY (const med_int ld_values, const med_int length_values,
70 const medModeSwitch mode=MED_FULL_INTERLACE);
71 MEDARRAY (T* values, const med_int ld_values,
72 const med_int length_values, const medModeSwitch mode=MED_FULL_INTERLACE);
73 MEDARRAY (MEDARRAY const &m);
74 MEDARRAY (MEDARRAY const &m, bool copyOther);
75 MEDARRAY & operator = (const MEDARRAY & m);
77 inline med_int getLeadingValue() const;
78 inline med_int getLengthValue() const;
80 const T * get (const medModeSwitch mode) ;
81 const T * getRow (const med_int i) ;
82 const T * getColumn (const med_int j) ;
83 const T getIJ (const med_int i, const med_int j) const;
84 // T * const get (const medModeSwitch mode) const;
85 // T * const getRow (const med_int i) const;
86 // T * const getColumn (const med_int j) const;
87 // T const getIJ (const med_int i, const med_int j) const;
89 inline medModeSwitch getMode() const;
91 void set (const medModeSwitch mode,const T* value);
92 void setI (const med_int i, const T* value);
93 void setJ (const med_int j, const T* value);
94 void setIJ (const med_int i, const med_int j, const T value);
96 void calculateOther();
97 bool isOtherCalculated() const {return (const T*)_valuesOther != NULL;}
98 void clearOtherMode();
102 //-------------------------------------------------//
104 // IMPLEMENTED CODE //
106 //-------------------------------------------------//
109 template <class T> inline MEDARRAY<T>::MEDARRAY():
110 _ldValues(0), _lengthValues(0), _mode(MED_FULL_INTERLACE),
111 _valuesFull(), _valuesNo(),
112 _valuesDefault(), _valuesOther()
116 // ------------------
118 template <class T> inline MEDARRAY<T>::~MEDARRAY()
122 // ------------------
124 /*! This constructor does allocation and does not set values : \n.
125 It allocates a "T" array of length_values*ld_values length.\n
126 You don't have to know the T values when calling this construtor
127 but you have to call "set" method to initialize them later.
128 You also can get the pointer to the memory zone (with "get" method),
130 The desallocation of T array is not your responsability. \n\n
131 Throws MEDEXCEPTION if T array length is < 1*/
133 template <class T> MEDARRAY<T>::MEDARRAY(const med_int ld_values,
134 const med_int length_values,
135 const medModeSwitch mode):
137 _ldValues(ld_values),
138 _lengthValues(length_values),
140 _valuesFull(), _valuesNo(),
141 _valuesDefault(),_valuesOther()
143 BEGIN_OF("constructor MEDARRAY<T>::MEDARRAY(const med_int, const med_int, const medModeSwitch)");
145 // if ld_values < 1 or length_values < 1
146 // throws an exception
147 // Pointers are setted to NULL
149 if ((ld_values<1)|(length_values<1))
151 throw MEDEXCEPTION(LOCALIZED("MEDARRAY<T>::MEDARRAY(const med_int, const med_int, const medModeSwitch) : dimension < 1 !"));
154 if ( _mode == MED_FULL_INTERLACE)
156 _valuesFull.set(length_values*ld_values);
157 _valuesDefault.set((T*) _valuesFull);
161 ASSERT (_mode == MED_NO_INTERLACE);
162 _valuesNo.set(length_values*ld_values);
163 _valuesDefault.set((T*)_valuesNo);
166 ASSERT( (T*)_valuesDefault != NULL);
167 SCRUTE((T*)_valuesDefault);
168 SCRUTE((T*)_valuesOther);
169 SCRUTE((T*)_valuesNo);
170 SCRUTE((T*)_valuesFull);
172 END_OF("constructor MEDARRAY<T>::MEDARRAY(const med_int, const med_int, const medModeSwitch ()");
175 // ------------------
177 /*! This constructor duplicate T*values.\n
179 Throws MEDEXCEPTION if the lenght of T is < 1*/
180 template <class T> MEDARRAY<T>::MEDARRAY( T*values,
181 const med_int ld_values,
182 const med_int length_values,
183 const medModeSwitch mode):
184 _ldValues(ld_values),
185 _lengthValues(length_values),
187 _valuesFull(),_valuesNo(),
188 _valuesDefault(),_valuesOther()
190 BEGIN_OF("constructor MEDARRAY<T>::MEDARRAY(T* values, const med_int, const med_int, const medModeSwitch)");
192 // if ld_values < 1 or length_values < 1, we could not allocate
193 // throws an exception
195 if ( (ld_values<1) | (length_values<1) )
197 throw MEDEXCEPTION(LOCALIZED("MEDARRAY<T>::MEDARRAY(T* values, const med_int, const medModeSwitch) : dimension < 1 !"));
199 if ( _mode == MED_FULL_INTERLACE)
201 _valuesFull.set(_ldValues*length_values,values);
202 _valuesDefault.set((T*)_valuesFull);
206 ASSERT (_mode == MED_NO_INTERLACE);
207 _valuesNo.set(_ldValues*length_values,values);
208 _valuesDefault.set((T*)_valuesNo);
211 ASSERT( (T*)_valuesDefault != NULL);
212 SCRUTE((T*)_valuesDefault);
213 SCRUTE((T*)_valuesOther);
214 SCRUTE((T*)_valuesNo);
215 SCRUTE((T*)_valuesFull);
217 END_OF("constructor MEDARRAY<T>::MEDARRAY(T* values, const med_int, const med_int, const medModeSwitch)");
220 // ------------------
222 /*! This constructor allocates a new medarray and does a copy of pointers/n
223 It DOES NOT copy the memory . The two objects will share the same data./n
224 (for copying data, use constructor MEDARRAY(MEDARRAY<T> const & m,bool copyOther). */
225 template <class T> MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m ):
226 _ldValues(m._ldValues),
227 _lengthValues(m._lengthValues),
229 _valuesFull((const T*)m._valuesFull),
230 _valuesNo((const T*)m._valuesNo),
231 _valuesDefault((const T*)m._valuesDefault),
232 _valuesOther((const T*)m._valuesOther)
234 BEGIN_OF("constructor MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m)");
235 ASSERT( (T*)_valuesDefault != NULL);
236 SCRUTE((T*)_valuesDefault);
237 SCRUTE((T*)_valuesOther);
238 SCRUTE((T*)_valuesNo);
239 SCRUTE((T*)_valuesFull);
240 END_OF("constructor MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m)");
243 /*! This constructor allocates a new array and does a copy of values
244 included in the m arrays./n
245 If the boolean is setted to true, both representations (in full mode
246 and no interlace mode) will be copied./n
247 Otherwise, only _valuesDefault will be copied./n
248 Desallocation of the arrays is not your reponsability./n/n
249 Throws MEDEXCEPTION if _valuesOther is null and copyOther equals true*/
250 template <class T> MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & p,bool copyOther ):
251 _ldValues(p._ldValues),
252 _lengthValues(p._lengthValues),
259 BEGIN_OF("Constructeur deepCopy MEDARRAY<T>::MEDARRAY(MEDARRAY<T> const & m,bool copyOther");
261 // PG : Non, s'il n'y a rien, on test et on ne copie rien, c'est tout !
263 // if ( copyOther==true && ((const T*)p._valuesOther==NULL))
265 // throw MEDEXCEPTION("MEDARRAY MEDARRAY const &m,bool copyOther : No Other values defined and bool = true !");
268 if ( _mode == MED_FULL_INTERLACE)
270 _valuesFull.set(p._ldValues*p._lengthValues,(const T*)p._valuesFull);
271 _valuesDefault.set((T*)_valuesFull);
273 if ((const T*)p._valuesNo != NULL)
275 _valuesNo.set(p._ldValues*p._lengthValues,(const T*)p._valuesNo);
276 _valuesOther.set((T*)_valuesNo);
281 ASSERT (_mode == MED_NO_INTERLACE);
282 _valuesNo.set(p._ldValues*p._lengthValues,(const T*)p._valuesNo);
283 _valuesDefault.set((T*)_valuesNo);
285 if ((const T*)p._valuesFull != NULL)
287 _valuesFull.set(p._ldValues*p._lengthValues,(const T*)p._valuesFull);
288 _valuesOther.set((T*)_valuesFull);
293 // ------------------
295 // /*! This operator does a copy of pointers/n
296 // It DOES NOT copy of the memory.
297 // The two objects will share data./n */
299 template <class T> MEDARRAY<T> & MEDARRAY<T>::operator = (const MEDARRAY & m)
302 BEGIN_OF("Operator = MEDARRAY<T>");
304 _ldValues=m._ldValues;
305 _lengthValues=m._lengthValues;
310 if ((const T*) m._valuesFull !=NULL)
311 _valuesFull.set(_ldValues*_lengthValues,(const T*) m._valuesFull);
313 if ((const T*) m._valuesNo !=NULL)
314 _valuesNo.set(_ldValues*_lengthValues,(const T*) m._valuesNo);
316 if (_mode == MED_FULL_INTERLACE) {
317 //PN : pour enlever les warning compilateur
318 //_valuesDefault.set((const T*) _valuesFull);
319 //_valuesOther.set((const T*) _valuesNo);
320 _valuesDefault.set((T*) _valuesFull);
321 _valuesOther.set((T*) _valuesNo);
323 ASSERT (_mode == MED_NO_INTERLACE);
324 //PN : pour enlever les warning compilateur
325 //_valuesDefault.set((const T*) _valuesNo);
326 //_valuesOther.set((const T*) _valuesFull);
327 _valuesDefault.set((T*) _valuesNo);
328 _valuesOther.set((T*) _valuesFull);
331 SCRUTE((T*)_valuesDefault);
332 SCRUTE((T*)_valuesOther);
333 SCRUTE((T*)_valuesNo);
334 SCRUTE((T*)_valuesFull);
336 END_OF("Operator = MEDARRAY<T>");
340 // ------------------
342 /*! returns _ldValues. (for example, space dimension for coordinates array)*/
343 template <class T> inline med_int MEDARRAY<T>::getLeadingValue() const
348 // ------------------
350 /*! returns _ldValues. (for example, number of nodes for coordinates array)*/
351 template <class T> inline med_int MEDARRAY<T>::getLengthValue() const
353 return _lengthValues;
356 // ------------------
358 /*! returns a pointer to _valuesDefault or _valuesOther, depending on
359 mode value : if mode is the same as _mode, _valuesDefault is returned.
360 else, if _valuesOther is calculated (if necessary) and then returned.
361 The pointer can be used to set values */
362 template <class T> const T* MEDARRAY<T>::get(const medModeSwitch mode)
364 BEGIN_OF("MEDARRAY<T>::get(const medModeSwitch mode)");
365 if ((T*)_valuesDefault == NULL)
367 throw MEDEXCEPTION("MEDARRAY::get(mode) : No values defined !");
371 //PN : pour enlever les warning compilateurs
372 //return (const T*)_valuesDefault;
373 return (T*) _valuesDefault;
377 if ((T*)_valuesOther == NULL)
381 //PN : pour enlever les warning compilateurs
382 //return (const T*)_valuesDefault;
383 return (T*) _valuesOther;
385 END_OF("MEDARRAY<T>::get(const medModeSwitch mode)");
388 // ------------------
390 /*! returns a pointer to ith element of the array.
391 (ith line in a MED_FULL_INTERLACE representation )/n
392 Be aware : if _mode is MED_NO_INTERLACE, the entire
393 array will be recalculate in MED_FULL_INTERLACE representation./n*/
395 template <class T> const T* MEDARRAY<T>::getRow(const med_int i)
398 BEGIN_OF("MEDARRAY<T>::getRow(const med_int i)");
400 if ((T*)_valuesDefault == NULL)
402 throw MEDEXCEPTION("MEDARRAY::getRow(i) : No values defined !");
406 throw MEDEXCEPTION("MEDARRAY::getRow(i) : argument i must be >= 1");
410 throw MEDEXCEPTION("MEDARRAY::getRow(i) : argument i must be <= _lengthValues");
413 if ((T*)_valuesFull == NULL)
415 ASSERT(((T*) _valuesDefault)==((T*) _valuesNo));
418 ASSERT((T*)_valuesFull != NULL);
420 // PN pour enlever les warning compilateurs
421 //const T* ptr = (const T*)_valuesFull + (i-1)*_ldValues;
422 const T* ptr = (T*) _valuesFull + (i-1)*_ldValues;
424 END_OF("MEDARRAY<T>::getRow(const med_int i )");
427 // ------------------
429 /*! this method is similar to getRow method./n
430 It returns a pointer to jth line of the array in a MED_NO-INTERLACE representation
431 (for example, 2nd coordinates)./n
432 Be aware : if _mode is MED_FULL_INTERLACE, the entire
433 array will be recalculate in MED_NO_INTERLACE representation./n*/
435 template <class T> const T* MEDARRAY<T>::getColumn(const med_int j)
437 BEGIN_OF("MEDARRAY<T>::getColumn(const med_int j)");
438 if ((T*)_valuesDefault == NULL)
440 throw MEDEXCEPTION("MEDARRAY::getColumn(j) : No values defined !");
444 throw MEDEXCEPTION("MEDARRAY::getColumn(j) : argument j must be >= 1");
448 throw MEDEXCEPTION("MEDARRAY::getColumn(j) : argument j must be <= _ldValues");
451 if ((T*)_valuesNo == NULL)
453 ASSERT(((T*) _valuesDefault)==((T*) _valuesFull));
456 //PN pour enlever les warning compilateur
457 //const T* ptr = (const T*)_valuesNo + (j-1)*_lengthValues;
458 const T* ptr = ( T*)_valuesNo + (j-1)*_lengthValues;
463 // ------------------
465 /*! returns Jth value of Ith element .\n
466 don't forget first element is element 1 (and not element 0). */
467 template <class T> const T MEDARRAY<T>::getIJ(const med_int i,const med_int j) const
469 BEGIN_OF("MEDARRAY<T>::getIJ(const med_int i, const med_int j)");
472 throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument i must be >= 1");
476 throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument i must be <= _lengthValues");
480 throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument j must be >= 1");
484 throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : argument j must be <= _ldValues");
487 if ( (const T*)_valuesDefault == NULL)
489 throw MEDEXCEPTION("MEDARRAY::getIJ(i,j) : No value in array !");
492 if (_mode == MED_FULL_INTERLACE)
494 return _valuesDefault[(i-1)*_ldValues+j-1];
498 return _valuesDefault[(j-1)*_lengthValues+i-1];
500 END_OF("MEDARRAY<T>::getIJ(const med_int i, const med_int j)");
503 // ------------------
505 /*! returns the default mode (_mode)/n
506 (internal use : needed by write method) */
507 template <class T> inline medModeSwitch MEDARRAY<T>::getMode() const
509 BEGIN_OF("MEDARRAY<T>::getMode()");
510 END_OF("MEDARRAY<T>::getMode()");
514 // ------------------
516 /*! sets T pointer of _valuesDefault (cf class PointerOf) on value.\n
517 no copy of value is done. \n
518 the other representation mode is not recalculate.
519 the corresponding pointers are setted to null */
520 // template <class T> void MEDARRAY<T>::set(const medModeSwitch mode, const T* value)
523 // BEGIN_OF("MEDARRAY<T>::set(mode,value)");
526 // if ( _mode == MED_FULL_INTERLACE)
528 // _valuesFull.set(value);
529 // _valuesDefault.set((T*)_valuesFull);
534 // ASSERT (_mode == MED_NO_INTERLACE);
535 // _valuesNo.set(value);
536 // _valuesDefault.set((T*)_valuesNo);
537 // _valuesFull.set(0);
539 // _valuesOther.set(0);
540 // END_OF("MEDARRAY<T>::set(mode,i,value)");
543 // set with duplication because we don't know were value come and
544 // MEDARRAY must have properties on it !!!!
545 template <class T> void MEDARRAY<T>::set(const medModeSwitch mode, const T* value)
547 BEGIN_OF("MEDARRAY<T>::set(mode,value)");
550 if ( _mode == MED_FULL_INTERLACE)
552 _valuesFull.set(_ldValues*_lengthValues,value);
553 _valuesDefault.set((T*)_valuesFull);
558 ASSERT (_mode == MED_NO_INTERLACE);
559 _valuesNo.set(_ldValues*_lengthValues,value);
560 _valuesDefault.set((T*)_valuesNo);
565 END_OF("MEDARRAY<T>::set(mode,i,value)");
568 /*! This function clears the other mode of representation if it exists
569 * It is usefull for people who needs for optimisation reasons to work directly
570 * on the inside array without using set-functions
572 template <class T> void MEDARRAY<T>::clearOtherMode()
574 if(isOtherCalculated())
576 if ( _mode == MED_FULL_INTERLACE)
585 // ------------------
587 /*! Sets ith element to T* values\n
588 if they both exist, both _valuesFull and _valuesNo arrays will be updated./n
589 Throws exception if i < 1 or i > _lengthValues */
590 template <class T> void MEDARRAY<T>::setI(const med_int i, const T* value)
592 BEGIN_OF("MEDARRAY<T>::setI(i,value)");
594 if ((T*)_valuesDefault == NULL)
596 throw MEDEXCEPTION("MEDARRAY::setI(i,value) : No values defined !");
600 throw MEDEXCEPTION("MEDARRAY::setI(i,value) : argument i must be > 0");
602 if ( i > _lengthValues)
604 throw MEDEXCEPTION("MEDARRAY::setI(i,value) : argument i must be <= _lenghtValues");
607 if ((T*)_valuesFull != NULL)
609 for (int k = 0;k<_ldValues;k++)
611 _valuesFull[k+_ldValues*(i-1)] = value[k];
615 if ((T*)_valuesNo != NULL)
617 for (int k = 0;k<_ldValues;k++)
619 _valuesNo[k*_lengthValues +(i-1)] = value[k];
623 END_OF("MEDARRAY::setI(i,value)");
625 // ------------------
627 /*! Sets ith element to T* values\n
628 if they both exist, both _valuesFull and _valuesNo arrays will be updated./n
629 Throws exception if i < 1 or i > _lengthValues */
630 template <class T> void MEDARRAY<T>::setJ(const med_int j, const T* value)
632 BEGIN_OF("MEDARRAY::setJ(j,value)");
633 if (( T*)_valuesDefault == NULL)
635 throw MEDEXCEPTION("MEDARRAY::setJ(j) : No values defined !");
639 throw MEDEXCEPTION("MEDARRAY::setJ(j) : argument j must be >= 1");
643 throw MEDEXCEPTION("MEDARRAY::setJ(j) : argument j must be <= _ldValues");
645 if ((T*)_valuesFull != NULL)
647 for (int k = 0;k<_lengthValues;k++)
649 _valuesFull[k*_ldValues+(j-1)] = value[k];
653 if ((T*)_valuesNo != NULL)
655 for (int k = 0;k<_lengthValues;k++)
657 _valuesNo[k+_lengthValues*(j-1)] = value[k];
660 END_OF("MEDARRAY::setJ(j,value)");
663 // ------------------
665 /*! Sets value of Jth coordinate of Ith element to T value./n
666 Maintains coherency./n
667 Throws exception if we don't have
668 1<=i<=_lengthValues and 1<=j<=_ldValues */
669 template <class T> void MEDARRAY<T>::setIJ(const med_int i, const med_int j, const T value)
671 // 1<=i<=_lengthValues and 1<=j<=_ldValues
674 throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument i must be >= 1");
676 throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument i must be <= _lengthValues");
679 throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument j must be >= 1");
681 throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : argument j must be <= _ldValues");
683 if ((T*)_valuesDefault == NULL)
685 throw MEDEXCEPTION("MEDARRAY::setIJ(i,j,value) : No value in array !");
688 if ((T*)_valuesFull != NULL)
690 _valuesFull[j-1+_ldValues*(i-1)] = value;
692 if ((T*)_valuesNo != NULL)
694 _valuesNo[(j-1)*_lengthValues+i-1] = value;
698 /*! Calculates the other mode of representation : MED_FULL_INTERLACE
699 if __mode = MED_NO_INTERLACE and vice versa./n
700 Throws exception if no value are setted */
701 template <class T> void MEDARRAY<T>::calculateOther()
703 BEGIN_OF("MEDARRAY<T>::calculateOther()");
704 if ((T*)_valuesDefault == NULL)
706 throw MEDEXCEPTION("MEDARRAY::calculateOther() : No values defined !");
709 if ((T*)_valuesOther == NULL)
711 _valuesOther.set(_ldValues*_lengthValues);
713 if (_mode == MED_NO_INTERLACE)
715 _valuesFull.set((T*)_valuesOther);
719 ASSERT( _mode==MED_FULL_INTERLACE);
720 _valuesNo.set((T*)_valuesOther);
723 for (int i=0; i<_lengthValues;i++)
725 for (int j=0; j<_ldValues; j++)
727 if (_mode == MED_NO_INTERLACE)
729 _valuesFull[i*_ldValues+j] = _valuesNo[j*_lengthValues+i];
733 _valuesNo[j*_lengthValues+i]=_valuesFull[i*_ldValues+j];
737 END_OF("MEDARRAY<T>::calculateOther()");
740 # endif /* # ifndef __MEDARRAY_H__ */