Salome HOME
Merge from V6_main (04/10/2012)
[modules/med.git] / src / MEDCoupling / MEDCouplingMemArray.txx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
2 //
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 // Author : Anthony Geay (CEA/DEN)
20 #ifndef __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__
21 #define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__
22
23 #include "MEDCouplingMemArray.hxx"
24 #include "NormalizedUnstructuredMesh.hxx"
25 #include "InterpKernelException.hxx"
26 #include "InterpolationUtils.hxx"
27
28 #include <sstream>
29 #include <algorithm>
30
31 namespace ParaMEDMEM
32 {
33   template<class T>
34   void MEDCouplingPointer<T>::setInternal(T *pointer)
35   {
36     _internal=pointer;
37     _external=0;
38   }
39
40   template<class T>
41   void MEDCouplingPointer<T>::setExternal(const T *pointer)
42   {
43     _external=pointer;
44     _internal=0;
45   }
46
47   template<class T>
48   MemArray<T>::MemArray(const MemArray<T>& other):_nb_of_elem(-1),_ownership(false),_dealloc(CPP_DEALLOC)
49   {
50     if(!other._pointer.isNull())
51       {
52         T *pointer=new T[other._nb_of_elem];
53         std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+other._nb_of_elem,pointer);
54         useArray(pointer,true,CPP_DEALLOC,other._nb_of_elem);
55       }
56   }
57
58   template<class T>
59   void MemArray<T>::useArray(const T *array, bool ownership, DeallocType type, int nbOfElem)
60   {
61     _nb_of_elem=nbOfElem;
62     destroy();
63     if(ownership)
64       _pointer.setInternal(const_cast<T *>(array));
65     else
66       _pointer.setExternal(array);
67     _ownership=ownership;
68     _dealloc=type;
69   }
70
71   template<class T>
72   void MemArray<T>::useExternalArrayWithRWAccess(const T *array, int nbOfElem)
73   {
74     _nb_of_elem=nbOfElem;
75     destroy();
76     _pointer.setInternal(const_cast<T *>(array));
77     _ownership=false;
78     _dealloc=CPP_DEALLOC;
79   }
80   
81   template<class T>
82   void MemArray<T>::writeOnPlace(int id, T element0, const T *others, int sizeOfOthers)
83   {
84     if(id+sizeOfOthers>=_nb_of_elem)
85       reAlloc(2*_nb_of_elem+sizeOfOthers+1);
86     T *pointer=_pointer.getPointer();
87     pointer[id]=element0;
88     std::copy(others,others+sizeOfOthers,pointer+id+1);
89   }
90
91   template<class T>
92   bool MemArray<T>::isEqual(const MemArray<T>& other, T prec, std::string& reason) const
93   {
94     std::ostringstream oss; oss.precision(15);
95     if(_nb_of_elem!=other._nb_of_elem)
96       {
97         oss << "Number of elements in coarse data of DataArray mismatch : this=" << _nb_of_elem << " other=" << other._nb_of_elem;
98         reason=oss.str();
99         return false;
100       }
101     const T *pt1=_pointer.getConstPointer();
102     const T *pt2=other._pointer.getConstPointer();
103     if(pt1==0 && pt2==0)
104       return true;
105     if(pt1==0 || pt2==0)
106       {
107         oss << "coarse data pointer is defined for only one DataArray instance !";
108         reason=oss.str();
109         return false;
110       }
111     if(pt1==pt2)
112       return true;
113     for(int i=0;i<_nb_of_elem;i++)
114       if(pt1[i]-pt2[i]<-prec || (pt1[i]-pt2[i])>prec)
115         {
116           oss << "The content of data differs at pos #" << i << " of coarse data ! this[i]=" << pt1[i] << " other[i]=" << pt2[i];
117           reason=oss.str();
118           return false;
119         }
120     return true;
121   }
122   
123   /*!
124    * @param sl is typically the number of components [in parameter]
125    */
126   template<class T>
127   void MemArray<T>::repr(int sl, std::ostream& stream) const
128   {
129     stream << "Number of tuples : ";
130     if(!_pointer.isNull())
131       {
132         if(sl!=0)
133           stream << _nb_of_elem/sl;
134         else
135           stream << "Empty Data";
136       }
137     else
138       stream << "No data";
139     stream << "\n";
140     stream << "Data content :\n";
141     const T *data=getConstPointer();
142     if(!_pointer.isNull())
143       {
144         if(_nb_of_elem!=0 && sl!=0)
145           {
146             int nbOfTuples=_nb_of_elem/sl;
147             for(int i=0;i<nbOfTuples;i++)
148               {
149                 stream << "Tuple #" << i << " : ";
150                 std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
151                 stream << "\n";
152                 data+=sl;
153               }
154           }
155         else
156           stream << "Empty Data\n";
157       }
158     else
159       stream << "No data !\n";
160   }
161   
162   /*!
163    * @param sl is typically the number of components [in parameter]
164    */
165   template<class T>
166   void MemArray<T>::reprZip(int sl, std::ostream& stream) const
167   {
168     stream << "Number of tuples : ";
169     if(!_pointer.isNull())
170       {
171         if(sl!=0)
172           stream << _nb_of_elem/sl;
173         else
174           stream << "Empty Data";
175       }
176     else
177       stream << "No data";
178     stream << "\n";
179     stream << "Data content : ";
180     const T *data=getConstPointer();
181     if(!_pointer.isNull())
182       {
183         if(_nb_of_elem!=0 && sl!=0)
184           {
185             int nbOfTuples=_nb_of_elem/sl;
186             for(int i=0;i<nbOfTuples;i++)
187               {
188                 stream << "|";
189                 std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
190                 stream << "| ";
191                 data+=sl;
192               }
193             stream << "\n";
194           }
195         else
196           stream << "Empty Data\n";
197       }
198     else
199       stream << "No data !\n";
200   }
201   
202   template<class T>
203   void MemArray<T>::fillWithValue(const T& val)
204   {
205     T *pt=_pointer.getPointer();
206     std::fill(pt,pt+_nb_of_elem,val);
207   }
208   
209   template<class T>
210   T *MemArray<T>::fromNoInterlace(int nbOfComp) const
211   {
212     const T *pt=_pointer.getConstPointer();
213     int nbOfTuples=_nb_of_elem/nbOfComp;
214     T *ret=new T[_nb_of_elem];
215     T *w=ret;
216     for(int i=0;i<nbOfTuples;i++)
217       for(int j=0;j<nbOfComp;j++,w++)
218         *w=pt[j*nbOfTuples+i];
219     return ret;
220   }
221   
222   template<class T>
223   T *MemArray<T>::toNoInterlace(int nbOfComp) const
224   {
225     const T *pt=_pointer.getConstPointer();
226     int nbOfTuples=_nb_of_elem/nbOfComp;
227     T *ret=new T[_nb_of_elem];
228     T *w=ret;
229     for(int i=0;i<nbOfComp;i++)
230       for(int j=0;j<nbOfTuples;j++,w++)
231         *w=pt[j*nbOfComp+i];
232     return ret;
233   }
234
235   template<class T>
236   void MemArray<T>::sort(bool asc)
237   {
238     T *pt=_pointer.getPointer();
239     if(asc)
240       std::sort(pt,pt+_nb_of_elem);
241     else
242       {
243         typename std::reverse_iterator<T *> it1(pt+_nb_of_elem);
244         typename std::reverse_iterator<T *> it2(pt);
245         std::sort(it1,it2);
246       }
247   }
248
249   template<class T>
250   void MemArray<T>::reverse()
251   {
252     T *pt=_pointer.getPointer();
253     std::reverse(pt,pt+_nb_of_elem);
254   }
255
256   template<class T>
257   void MemArray<T>::alloc(int nbOfElements) throw(INTERP_KERNEL::Exception)
258   {
259     destroy();
260     if(nbOfElements<0)
261       throw INTERP_KERNEL::Exception("MemArray::alloc : request for negative length of data !");
262     _nb_of_elem=nbOfElements;
263     _pointer.setInternal(new T[_nb_of_elem]);
264     _ownership=true;
265     _dealloc=CPP_DEALLOC;
266   }
267   
268   template<class T>
269   void MemArray<T>::reAlloc(int newNbOfElements) throw(INTERP_KERNEL::Exception)
270   {
271     if(newNbOfElements<0)
272       throw INTERP_KERNEL::Exception("MemArray::reAlloc : request for negative length of data !");
273     T *pointer=new T[newNbOfElements];
274     std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<int>(_nb_of_elem,newNbOfElements),pointer);
275     if(_ownership)
276       destroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external
277     _pointer.setInternal(pointer);
278     _nb_of_elem=newNbOfElements;
279     _ownership=true;
280     _dealloc=CPP_DEALLOC;
281   }
282
283   template<class T>
284   void MemArray<T>::destroyPointer(T *pt, DeallocType type)
285   {
286     switch(type)
287       {
288       case CPP_DEALLOC:
289         {
290           delete [] pt;
291           return ;
292         }
293       case C_DEALLOC:
294         {
295           free(pt);
296           return ;
297         }
298       default:
299         std::ostringstream stream;
300         stream << "Invalid deallocation requested for pointer " << pt;
301         throw INTERP_KERNEL::Exception(stream.str().c_str());
302       }
303   }
304
305   template<class T>
306   void MemArray<T>::destroy()
307   {
308     if(_ownership)
309       destroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external
310     _pointer.null();
311     _ownership=false;
312   }
313   
314   template<class T>
315   MemArray<T> &MemArray<T>::operator=(const MemArray<T>& other)
316   {
317     alloc(other._nb_of_elem);
318     std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+_nb_of_elem,_pointer.getPointer());
319     return *this;
320   }
321 }
322
323 #endif