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