Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/med.git] / src / MEDMEM / MEDMEM_nArray.hxx
1 //  Copyright (C) 2007-2008  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 #ifndef MEDMEM_ARRAY_HXX
23 #define MEDMEM_ARRAY_HXX
24
25 #include "MEDMEM.hxx"
26
27 #include "MEDMEM_InterlacingPolicy.hxx"
28 #include "MEDMEM_IndexCheckingPolicy.hxx"
29
30 #include "MEDMEM_PointerOf.hxx"
31 #include "MEDMEM_define.hxx"
32
33 namespace MEDMEM {
34
35 class MEDMEM_EXPORT MEDMEM_Array_ {
36 public:
37   //virtual void dummy() {};
38   virtual bool getGaussPresence() const { return false; }
39   virtual MED_EN::medModeSwitch getInterlacingType() const {return MED_EN::MED_UNDEFINED_INTERLACE;}
40   virtual ~MEDMEM_Array_() {}; //Indispensable pour détruire le vrai objet pointé
41 };
42
43 template < class ARRAY_ELEMENT_TYPE,
44            class INTERLACING_POLICY=FullInterlaceNoGaussPolicy,
45            class CHECKING_POLICY=IndexCheckPolicy >
46 class MEDMEM_Array : public INTERLACING_POLICY, public CHECKING_POLICY, public MEDMEM_Array_ {
47
48 public :
49
50   typedef ARRAY_ELEMENT_TYPE  ElementType;
51   typedef INTERLACING_POLICY  InterlacingPolicy;
52   typedef CHECKING_POLICY     CheckingPolicy;
53
54 public  :
55   MEDMEM_Array():_array( ( ElementType *) NULL)  {}; //Interdit le constructeur par défaut, peut pas à  cause du FIELD
56
57   ~MEDMEM_Array() {
58     // PointerOf s'occupe de la desallocation.
59   };
60
61   // Le mot clé inline permettra d'instancier le constructeur uniquement
62   // s'il est appelé ( ...NoGaussPolicy)
63   // Rem : Le constructeur de la policy demandée est appelé
64   inline MEDMEM_Array(int dim, int nbelem) : InterlacingPolicy(nbelem,dim)
65   {
66     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
67     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
68     _array.set(InterlacingPolicy::_arraySize);
69   };
70
71   // Le mot clé inline permettra d'instancier le constructeur uniquement
72   // s'il est appelé NoInterlaceByTypeNoGaussPolicy(...)
73   // Rem : Le constructeur de la policy demandée est appelé
74   inline MEDMEM_Array(int dim, int nbelem,
75                       int nbtypegeo, const int * const nbelgeoc)
76     : InterlacingPolicy(nbelem, dim, nbtypegeo, nbelgeoc)
77   {
78     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
79     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
80     _array.set(InterlacingPolicy::_arraySize);
81   };
82
83   // Le mot clé inline permettra d'instancier le constructeur uniquement
84   // s'il est appelé ( ...NoGaussPolicy)
85   // Rem : Le constructeur de la policy demandée est appelé
86   inline MEDMEM_Array( ElementType * values, int dim, int nbelem,
87                        bool shallowCopy=false,
88                        bool ownershipOfValues=false) : InterlacingPolicy(nbelem,dim)
89   {
90     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
91     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
92     if(shallowCopy)
93
94       if(ownershipOfValues)
95         _array.setShallowAndOwnership((const ElementType *)values);
96       else
97         _array.set((const ElementType*)values);
98
99     else // Cas par défaut
100       _array.set(InterlacingPolicy::_arraySize,values);
101
102   }
103
104   // Le mot clé inline permettra d'instancier le constructeur uniquement
105   // s'il est appelé NoInterlaceByTypeNoGaussPolicy(...)
106   // Rem : Le constructeur de la policy demandée est appelé
107   inline MEDMEM_Array( ElementType * values, int dim, int nbelem,
108                        int nbtypegeo, const int * const  nbelgeoc,
109                        bool shallowCopy=false,
110                        bool ownershipOfValues=false) 
111     : InterlacingPolicy(nbelem, dim, nbtypegeo, nbelgeoc)
112   {
113     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
114     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
115     if(shallowCopy)
116
117       if(ownershipOfValues)
118         _array.setShallowAndOwnership((const ElementType *)values);
119       else
120         _array.set((const ElementType*)values);
121
122     else // Cas par défaut
123       _array.set(InterlacingPolicy::_arraySize,values);
124
125   }
126
127   // Le mot clé inline permettra d'instancier le constructeur uniquement
128   // s'il est appelé ( ...GaussPolicy)
129   // Rem : Le constructeur de la policy demandée est appelé
130   inline MEDMEM_Array(int dim, int nbelem, int nbtypegeo,
131                       const int * const  nbelgeoc, const int * const nbgaussgeo)
132     : InterlacingPolicy(nbelem, dim, nbtypegeo, nbelgeoc, nbgaussgeo)
133   {
134     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
135     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
136     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbtypegeo);
137     _array.set(InterlacingPolicy::_arraySize);
138   };
139
140
141   // Le mot clé inline permettra d'instancier le constructeur uniquement
142   // s'il est appelé ( ...GaussPolicy)
143   // Rem : Le constructeur de la policy demandée est appelé
144   inline MEDMEM_Array(ElementType * values, int dim, int nbelem, int nbtypegeo,
145                       const int * const  nbelgeoc, const int * const  nbgaussgeo,
146                       bool shallowCopy=false,
147                       bool ownershipOfValues=false)
148     : InterlacingPolicy(nbelem, dim, nbtypegeo, nbelgeoc, nbgaussgeo)
149   {
150     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbelem);
151     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",dim);
152     CHECKING_POLICY::checkMoreThanZero("MEDMEM_Array",nbtypegeo);
153
154     if(shallowCopy)
155
156       if(ownershipOfValues)
157         _array.setShallowAndOwnership((const ElementType *)values);
158       else
159         _array.set((const ElementType*)values);
160
161     else
162       _array.set(InterlacingPolicy::_arraySize,values);
163
164   };
165
166   // Constructeur de recopie pour un MEDMEM_Array avec les mêmes
167   // paramètres template qu'à la construction
168   inline MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false)
169     :InterlacingPolicy(array,shallowCopy)
170   {
171     if (shallowCopy)
172       this->_array.set(array._array); // Le propriétaire reste le ARRAY initial
173     else
174       this->_array.set(InterlacingPolicy::_arraySize,array._array);
175   }
176
177
178   // L'utilisation d'une copie superficielle pour l'opérateur d'affectation
179   // ne me parait pas être une bonne ideé : Compatibilité ancienne version MEDARRAY?
180   inline MEDMEM_Array<ElementType,InterlacingPolicy,CheckingPolicy> &
181          operator=( const MEDMEM_Array & array) {
182     if ( this == &array) return *this;
183   const char* LOC = "MEDMEM_Array  operator =";
184   BEGIN_OF_MED(LOC);
185     InterlacingPolicy::operator=(array); //Appel des classes de base ?
186
187     this->_array.set(array._array); // Le propriétaire reste le ARRAY initial
188
189     return *this;
190   }
191
192   MED_EN::medModeSwitch getInterlacingType() const {
193     return InterlacingPolicy::getInterlacingType();
194   }
195
196   bool getGaussPresence() const {
197     return InterlacingPolicy::getGaussPresence();
198   }
199
200   ElementType * getPtr() {
201     return  _array;
202   }
203
204   const ElementType * getPtr() const {
205     return  _array;
206   }
207
208   void setPtr(ElementType * values, bool shallowCopy=false,
209               bool ownershipOfValues=false) {
210
211     if(shallowCopy)
212
213       if(ownershipOfValues)
214         _array.setShallowAndOwnership((const ElementType *)values);
215       else
216         _array.set((const ElementType*)values);
217
218     else
219       _array.set(InterlacingPolicy::_arraySize,values);
220   }
221
222   inline const ElementType * getRow(int i) const {
223     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
224     // Empêche l'utilisation de getRow en mode MED_NO_INTERLACE
225     // Ne devrait pas dépendre de la politique check
226     checkEquality("MEDMEM_Array (Interlace test)",
227                   MED_EN::MED_NO_INTERLACE,
228                   InterlacingPolicy::_interlacing );
229     return &(_array[ InterlacingPolicy::getIndex(i,1) ]);
230
231   }
232
233   void setRow(int i,const ElementType * const value) {
234     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
235     // setRow fonctionne
236     // dans les deux modes d'entrelacement.
237
238     // int index = -1;
239     for (int j =1; j <= InterlacingPolicy::getDim(); j++) {
240       for (int k = 1 ; k <= InterlacingPolicy::getNbGauss(i); k++) {
241         _array[InterlacingPolicy::getIndex(i,j,k)] = value[InterlacingPolicy::getIndex(1,j,k)];
242         //index++;
243         //_array[InterlacingPolicy::getIndex(i,j,k)] = value[index];
244       }
245     }
246   }
247
248   inline const ElementType * getColumn(int j) const {
249     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
250     checkEquality("MEDMEM_Array (Interlace test)",
251                   MED_EN::MED_FULL_INTERLACE, InterlacingPolicy::_interlacing );
252     return &(_array[ InterlacingPolicy::getIndex(1,j) ]);
253   }
254
255   void setColumn(int j, const ElementType * const value) {
256     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
257     // setColumn fonctionne
258     // dans les deux modes d'entrelacement.
259
260     int index = -1;
261     for (int i=1; i <= InterlacingPolicy::getNbElem(); i++) {
262       for (int k = 1 ; k <= InterlacingPolicy::getNbGauss(i); k++) {
263         //_array[InterlacingPolicy::getIndex(i,j,k)] = value[InterlacingPolicy::getIndex(i,1,k)];
264         index++;
265         _array[InterlacingPolicy::getIndex(i,j,k)] = value[index];
266       }
267     }
268   }
269
270
271   inline const ElementType & getIJ(int i, int j) const  {
272     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
273     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
274     return _array[ InterlacingPolicy::getIndex(i,j) ];
275   }
276
277   inline const ElementType & getIJK(int i, int j, int k ) const {
278     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
279     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
280     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGauss(i),k);
281
282     return _array[ InterlacingPolicy::getIndex(i,j,k) ];
283   };
284
285   inline const ElementType & getIJByType(int i, int j, int t) const  {
286     if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
287       throw MEDEXCEPTION(LOCALIZED(STRING("Wrong interlacing type ") << getInterlacingType()));
288     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
289     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
290     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGeoType(),t);
291     if ( InterlacingPolicy::getGaussPresence() )
292       return _array[ ((NoInterlaceByTypeGaussPolicy*)this)->getIndexByType(i,j,t) ];
293     else
294       return _array[ ((NoInterlaceByTypeNoGaussPolicy*)this)->getIndexByType(i,j,t) ];
295   }
296
297   inline const ElementType & getIJKByType(int i, int j, int k, int t) const {
298     if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
299       throw MEDEXCEPTION(LOCALIZED(STRING("Wrong interlacing type ") << getInterlacingType()));
300     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
301     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGeoType(),t);
302     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
303
304     if ( InterlacingPolicy::getGaussPresence() ) {
305         // not compilable on Debian40
306 //       checkInInclusiveRange("MEDMEM_Array",
307 //                             1,((NoInterlaceByTypeGaussPolicy*)this)->getNbGaussByType(t),k);
308       int kmax = ((NoInterlaceByTypeGaussPolicy*)this)->getNbGaussByType(t);
309       if ( k < 1 || k > kmax )
310         throw MEDEXCEPTION(LOCALIZED(STRING("MEDMEM_Array::getIJKByType(), ")
311                                      << " k : " << k << " not in rang [1," << kmax <<"]"));
312       return _array[ ((NoInterlaceByTypeGaussPolicy*)this)->getIndexByType(i,j,k,t) ];
313     }
314     else {
315       checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGauss(i),k);
316       return _array[ ((NoInterlaceByTypeNoGaussPolicy*)this)->getIndexByType(i,j,k,t) ];
317     }
318   };
319
320   inline void setIJ(int i, int j, const ElementType & value) {   //autre signature avec
321     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
322     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
323
324     _array[ InterlacingPolicy::getIndex(i,j) ] = value;                      // retour ElementType & ?
325   };
326
327   inline void setIJByType(int i, int j, int t, const ElementType & value) {   //autre signature avec
328     if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
329       throw MEDEXCEPTION(LOCALIZED(STRING("Wrong interlacing type ") << getInterlacingType()));
330     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
331     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
332     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGeoType(),t);
333
334     if ( InterlacingPolicy::getGaussPresence() )
335       _array[ ((NoInterlaceByTypeGaussPolicy*)this)->getIndexByType(i,j,t) ] = value;
336     else
337       _array[ ((NoInterlaceByTypeNoGaussPolicy*)this)->getIndexByType(i,j,t) ] = value;
338   };
339
340   inline void setIJK(int i, int j, int k, const ElementType & value) {   //autre signature avec
341     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
342     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
343     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGauss(i),k);
344
345     _array[ InterlacingPolicy::getIndex(i,j,k) ] = value;                      // retour ElementType & ?
346   };
347
348   inline void setIJKByType(int i, int j, int k, int t, const ElementType & value) {   //autre signature avec
349     if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE )
350       throw MEDEXCEPTION(LOCALIZED(STRING("Wrong interlacing type ") << getInterlacingType()));
351     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_nbelem,i);
352     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::_dim,j);
353     checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGeoType(),t);
354
355     if ( InterlacingPolicy::getGaussPresence() ) {
356         // not compilable on Debian40
357 //       checkInInclusiveRange("MEDMEM_Array",
358 //                             1,((NoInterlaceByTypeGaussPolicy*)this)->getNbGaussByType(t),k);
359       int kmax = ((NoInterlaceByTypeGaussPolicy*)this)->getNbGaussByType(t);
360       if ( k < 1 || k > kmax )
361         throw MEDEXCEPTION(LOCALIZED(STRING("MEDMEM_Array::getIJKByType(), ")
362                                      << " k : " << k << " not in rang [1," << kmax <<"]"));
363       _array[ ((NoInterlaceByTypeGaussPolicy*)this)->getIndexByType(i,j,k,t) ] = value;
364     }
365     else {
366       checkInInclusiveRange("MEDMEM_Array",1,InterlacingPolicy::getNbGauss(i),k);
367       _array[ ((NoInterlaceByTypeNoGaussPolicy*)this)->getIndexByType(i,j,k,t) ] = value;
368     }
369   };
370
371   bool operator == (const MEDMEM_Array & array ) const {
372
373     if ( this == &array ) return true;
374
375     int size = array.getArraySize();
376     if ( size != this->getArraySize() ) return false;
377
378     ARRAY_ELEMENT_TYPE * arrayPtr =
379       const_cast<MEDMEM_Array &>(array).getPtr();
380     for (int i=0; i < size; ++i)
381       if (_array[i] != arrayPtr[i]) return false;
382
383     return true;
384   }
385
386   friend ostream & operator<<(ostream & os, const MEDMEM_Array & array) {
387
388     for (int i=1;i<=array.getNbElem();++i) {
389       for (int j=1; j<=array.getDim();++j)
390         for (int k=1;k<=array.getNbGauss(i);++k)
391           os << "Value [" << i << "," << j << "," << k << "] = " << array.getIJK(i,j,k) << ", ";
392       os << endl;
393     }
394     return os;
395   }
396
397 private:
398
399   PointerOf<ElementType> _array;
400 };
401
402 } //END NAMESPACE
403 #endif