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