1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #ifndef __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__
22 #define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__
24 #include "MEDCouplingMemArray.hxx"
25 #include "NormalizedUnstructuredMesh.hxx"
26 #include "InterpKernelException.hxx"
27 #include "InterpolationUtils.hxx"
35 void MEDCouplingPointer<T>::setInternal(T *pointer)
42 void MEDCouplingPointer<T>::setExternal(const T *pointer)
49 MemArray<T>::MemArray(const MemArray<T>& other):_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(CPP_DEALLOC)
51 if(!other._pointer.isNull())
53 _nb_of_elem_alloc=other._nb_of_elem;
54 T *pointer=new T[_nb_of_elem_alloc];
55 std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+other._nb_of_elem,pointer);
56 useArray(pointer,true,CPP_DEALLOC,other._nb_of_elem);
61 void MemArray<T>::useArray(const T *array, bool ownership, DeallocType type, int nbOfElem)
64 _nb_of_elem_alloc=nbOfElem;
67 _pointer.setInternal(const_cast<T *>(array));
69 _pointer.setExternal(array);
75 void MemArray<T>::useExternalArrayWithRWAccess(const T *array, int nbOfElem)
78 _nb_of_elem_alloc=nbOfElem;
80 _pointer.setInternal(const_cast<T *>(array));
86 void MemArray<T>::writeOnPlace(int id, T element0, const T *others, int sizeOfOthers)
88 if(id+sizeOfOthers>=_nb_of_elem_alloc)
89 reserve(2*_nb_of_elem+sizeOfOthers+1);
90 T *pointer=_pointer.getPointer();
92 std::copy(others,others+sizeOfOthers,pointer+id+1);
93 _nb_of_elem=std::max<int>(_nb_of_elem,id+sizeOfOthers+1);
97 template<class InputIterator>
98 void MemArray<T>::insertAtTheEnd(InputIterator first, InputIterator last)
100 T *pointer=_pointer.getPointer();
103 if(_nb_of_elem>=_nb_of_elem_alloc || _nb_of_elem==0)
105 reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1);
106 pointer=_pointer.getPointer();
108 pointer[_nb_of_elem++]=*first++;
113 void MemArray<T>::pushBack(T elem) throw(INTERP_KERNEL::Exception)
115 if(_nb_of_elem>=_nb_of_elem_alloc)
116 reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1);
118 pt[_nb_of_elem++]=elem;
122 T MemArray<T>::popBack() throw(INTERP_KERNEL::Exception)
126 const T *pt=getConstPointer();
127 return pt[--_nb_of_elem];
129 throw INTERP_KERNEL::Exception("MemArray::popBack : nothing to pop in array !");
133 void MemArray<T>::pack() const
136 (const_cast<MemArray<T> * >(this))->reserve(_nb_of_elem);
140 bool MemArray<T>::isEqual(const MemArray<T>& other, T prec, std::string& reason) const
142 std::ostringstream oss; oss.precision(15);
143 if(_nb_of_elem!=other._nb_of_elem)
145 oss << "Number of elements in coarse data of DataArray mismatch : this=" << _nb_of_elem << " other=" << other._nb_of_elem;
149 const T *pt1=_pointer.getConstPointer();
150 const T *pt2=other._pointer.getConstPointer();
155 oss << "coarse data pointer is defined for only one DataArray instance !";
161 for(int i=0;i<_nb_of_elem;i++)
162 if(pt1[i]-pt2[i]<-prec || (pt1[i]-pt2[i])>prec)
164 oss << "The content of data differs at pos #" << i << " of coarse data ! this[i]=" << pt1[i] << " other[i]=" << pt2[i];
172 * \param [in] sl is typically the number of components
175 void MemArray<T>::repr(int sl, std::ostream& stream) const
177 stream << "Number of tuples : ";
178 if(!_pointer.isNull())
181 stream << _nb_of_elem/sl << std::endl << "Internal memory facts : " << _nb_of_elem << "/" << _nb_of_elem_alloc;
183 stream << "Empty Data";
188 stream << "Data content :\n";
189 const T *data=getConstPointer();
190 if(!_pointer.isNull())
192 if(_nb_of_elem!=0 && sl!=0)
194 int nbOfTuples=_nb_of_elem/sl;
195 for(int i=0;i<nbOfTuples;i++)
197 stream << "Tuple #" << i << " : ";
198 std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
204 stream << "Empty Data\n";
207 stream << "No data !\n";
211 * \param [in] sl is typically the number of components
214 void MemArray<T>::reprZip(int sl, std::ostream& stream) const
216 stream << "Number of tuples : ";
217 if(!_pointer.isNull())
220 stream << _nb_of_elem/sl;
222 stream << "Empty Data";
227 stream << "Data content : ";
228 const T *data=getConstPointer();
229 if(!_pointer.isNull())
231 if(_nb_of_elem!=0 && sl!=0)
233 int nbOfTuples=_nb_of_elem/sl;
234 for(int i=0;i<nbOfTuples;i++)
237 std::copy(data,data+sl,std::ostream_iterator<T>(stream," "));
244 stream << "Empty Data\n";
247 stream << "No data !\n";
251 void MemArray<T>::fillWithValue(const T& val)
253 T *pt=_pointer.getPointer();
254 std::fill(pt,pt+_nb_of_elem,val);
258 T *MemArray<T>::fromNoInterlace(int nbOfComp) const
260 const T *pt=_pointer.getConstPointer();
261 int nbOfTuples=_nb_of_elem/nbOfComp;
262 T *ret=new T[_nb_of_elem];
264 for(int i=0;i<nbOfTuples;i++)
265 for(int j=0;j<nbOfComp;j++,w++)
266 *w=pt[j*nbOfTuples+i];
271 T *MemArray<T>::toNoInterlace(int nbOfComp) const
273 const T *pt=_pointer.getConstPointer();
274 int nbOfTuples=_nb_of_elem/nbOfComp;
275 T *ret=new T[_nb_of_elem];
277 for(int i=0;i<nbOfComp;i++)
278 for(int j=0;j<nbOfTuples;j++,w++)
284 void MemArray<T>::sort(bool asc)
286 T *pt=_pointer.getPointer();
288 std::sort(pt,pt+_nb_of_elem);
291 typename std::reverse_iterator<T *> it1(pt+_nb_of_elem);
292 typename std::reverse_iterator<T *> it2(pt);
298 void MemArray<T>::reverse()
300 T *pt=_pointer.getPointer();
301 std::reverse(pt,pt+_nb_of_elem);
305 void MemArray<T>::alloc(int nbOfElements) throw(INTERP_KERNEL::Exception)
309 throw INTERP_KERNEL::Exception("MemArray::alloc : request for negative length of data !");
310 _nb_of_elem=nbOfElements;
311 _nb_of_elem_alloc=nbOfElements;
312 _pointer.setInternal(new T[_nb_of_elem_alloc]);
314 _dealloc=CPP_DEALLOC;
318 * This method performs systematically an allocation of \a newNbOfElements elements in \a this.
319 * \a _nb_of_elem and \a _nb_of_elem_alloc will \b NOT be systematically equal (contrary to MemArray<T>::reAlloc method.
320 * So after the call of this method \a _nb_of_elem will be equal tostd::min<int>(_nb_of_elem,newNbOfElements) and \a _nb_of_elem_alloc equal to
321 * \a newNbOfElements. This method is typically used to perform a pushBack to avoid systematic allocations-copy-deallocation.
322 * So after the call of this method the accessible content is perfectly set.
324 * So this method should not be confused with MemArray<T>::reserve that is close to MemArray<T>::reAlloc but not same.
327 void MemArray<T>::reserve(int newNbOfElements) throw(INTERP_KERNEL::Exception)
329 if(newNbOfElements<0)
330 throw INTERP_KERNEL::Exception("MemArray::reAlloc : request for negative length of data !");
331 if(_nb_of_elem_alloc==newNbOfElements)
333 T *pointer=new T[newNbOfElements];
334 std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<int>(_nb_of_elem,newNbOfElements),pointer);
336 destroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external
337 _pointer.setInternal(pointer);
338 _nb_of_elem=std::min<int>(_nb_of_elem,newNbOfElements);
339 _nb_of_elem_alloc=newNbOfElements;
341 _dealloc=CPP_DEALLOC;
345 * This method performs systematically an allocation of \a newNbOfElements elements in \a this.
346 * \a _nb_of_elem and \a _nb_of_elem_alloc will be equal even if only std::min<int>(_nb_of_elem,newNbOfElements) come from the .
347 * The remaing part of the new allocated chunk are available but not set previouly !
349 * So this method should not be confused with MemArray<T>::reserve that is close to MemArray<T>::reAlloc but not same.
352 void MemArray<T>::reAlloc(int newNbOfElements) throw(INTERP_KERNEL::Exception)
354 if(newNbOfElements<0)
355 throw INTERP_KERNEL::Exception("MemArray::reAlloc : request for negative length of data !");
356 if(_nb_of_elem==newNbOfElements)
358 T *pointer=new T[newNbOfElements];
359 std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<int>(_nb_of_elem,newNbOfElements),pointer);
361 destroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external
362 _pointer.setInternal(pointer);
363 _nb_of_elem=newNbOfElements;
364 _nb_of_elem_alloc=newNbOfElements;
366 _dealloc=CPP_DEALLOC;
370 void MemArray<T>::destroyPointer(T *pt, DeallocType type)
385 std::ostringstream stream;
386 stream << "Invalid deallocation requested for pointer " << pt;
387 throw INTERP_KERNEL::Exception(stream.str().c_str());
392 void MemArray<T>::destroy()
395 destroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external
401 MemArray<T> &MemArray<T>::operator=(const MemArray<T>& other)
403 alloc(other._nb_of_elem);
404 std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+_nb_of_elem,_pointer.getPointer());