X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FMEDCoupling%2FMEDCouplingMemArray.txx;h=90773df2bf988fdc97fb6522ffaf3af13a069222;hb=6bfd8d6afb47fa46fd8fa0bc98d7fe057790460c;hp=4c5339a8b6671a5e34484af5c29501115aa647cd;hpb=10f37bf6f33a762626d7f1093b2f5450c1688667;p=tools%2Fmedcoupling.git diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index 4c5339a8b..90773df2b 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -16,6 +16,8 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// Author : Anthony Geay (CEA/DEN) + #ifndef __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ #define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ @@ -25,6 +27,7 @@ #include "InterpolationUtils.hxx" #include +#include #include namespace ParaMEDMEM @@ -44,37 +47,93 @@ namespace ParaMEDMEM } template - MemArray::MemArray(const MemArray& other):_nb_of_elem(-1),_ownership(false),_dealloc(CPP_DEALLOC) + MemArray::MemArray(const MemArray& other):_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(0),_param_for_deallocator(0) { if(!other._pointer.isNull()) { - T *pointer=new T[other._nb_of_elem]; + _nb_of_elem_alloc=other._nb_of_elem; + T *pointer=(T*)malloc(_nb_of_elem_alloc*sizeof(T)); std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+other._nb_of_elem,pointer); - useArray(pointer,true,CPP_DEALLOC,other._nb_of_elem); + useArray(pointer,true,C_DEALLOC,other._nb_of_elem); } } template - void MemArray::useArray(const T *array, bool ownership, DeallocType type, int nbOfElem) + void MemArray::useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfElem) { - _nb_of_elem=nbOfElem; destroy(); + _nb_of_elem=nbOfElem; + _nb_of_elem_alloc=nbOfElem; if(ownership) _pointer.setInternal(const_cast(array)); else _pointer.setExternal(array); _ownership=ownership; - _dealloc=type; + _dealloc=BuildFromType(type); + } + + template + void MemArray::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfElem) + { + destroy(); + _nb_of_elem=nbOfElem; + _nb_of_elem_alloc=nbOfElem; + _pointer.setInternal(const_cast(array)); + _ownership=false; + _dealloc=CPPDeallocator; } template - void MemArray::writeOnPlace(int id, T element0, const T *others, int sizeOfOthers) + void MemArray::writeOnPlace(std::size_t id, T element0, const T *others, std::size_t sizeOfOthers) { - if(id+sizeOfOthers>=_nb_of_elem) - reAlloc(2*_nb_of_elem+sizeOfOthers+1); + if(id+sizeOfOthers>=_nb_of_elem_alloc) + reserve(2*_nb_of_elem+sizeOfOthers+1); T *pointer=_pointer.getPointer(); pointer[id]=element0; std::copy(others,others+sizeOfOthers,pointer+id+1); + _nb_of_elem=std::max(_nb_of_elem,id+sizeOfOthers+1); + } + + template + template + void MemArray::insertAtTheEnd(InputIterator first, InputIterator last) + { + T *pointer=_pointer.getPointer(); + while(first!=last) + { + if(_nb_of_elem>=_nb_of_elem_alloc) + { + reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1); + pointer=_pointer.getPointer(); + } + pointer[_nb_of_elem++]=*first++; + } + } + + template + void MemArray::pushBack(T elem) + { + if(_nb_of_elem>=_nb_of_elem_alloc) + reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1); + T *pt=getPointer(); + pt[_nb_of_elem++]=elem; + } + + template + T MemArray::popBack() + { + if(_nb_of_elem>0) + { + const T *pt=getConstPointer(); + return pt[--_nb_of_elem]; + } + throw INTERP_KERNEL::Exception("MemArray::popBack : nothing to pop in array !"); + } + + template + void MemArray::pack() const + { + (const_cast * >(this))->reserve(_nb_of_elem); } template @@ -99,7 +158,7 @@ namespace ParaMEDMEM } if(pt1==pt2) return true; - for(int i=0;i<_nb_of_elem;i++) + for(std::size_t i=0;i<_nb_of_elem;i++) if(pt1[i]-pt2[i]<-prec || (pt1[i]-pt2[i])>prec) { oss << "The content of data differs at pos #" << i << " of coarse data ! this[i]=" << pt1[i] << " other[i]=" << pt2[i]; @@ -108,18 +167,19 @@ namespace ParaMEDMEM } return true; } - + /*! - * @param sl is typically the number of components [in parameter] + * \param [in] sl is typically the number of components + * \return True if a not null pointer is present, False if not. */ template - void MemArray::repr(int sl, std::ostream& stream) const + bool MemArray::reprHeader(int sl, std::ostream& stream) const { stream << "Number of tuples : "; if(!_pointer.isNull()) { if(sl!=0) - stream << _nb_of_elem/sl; + stream << _nb_of_elem/sl << std::endl << "Internal memory facts : " << _nb_of_elem << "/" << _nb_of_elem_alloc; else stream << "Empty Data"; } @@ -127,13 +187,25 @@ namespace ParaMEDMEM stream << "No data"; stream << "\n"; stream << "Data content :\n"; - const T *data=getConstPointer(); - if(!_pointer.isNull()) + bool ret=!_pointer.isNull(); + if(!ret) + stream << "No data !\n"; + return ret; + } + + /*! + * \param [in] sl is typically the number of components + */ + template + void MemArray::repr(int sl, std::ostream& stream) const + { + if(reprHeader(sl,stream)) { + const T *data=getConstPointer(); if(_nb_of_elem!=0 && sl!=0) { - int nbOfTuples=_nb_of_elem/sl; - for(int i=0;i(stream," ")); @@ -144,12 +216,10 @@ namespace ParaMEDMEM else stream << "Empty Data\n"; } - else - stream << "No data !\n"; } - + /*! - * @param sl is typically the number of components [in parameter] + * \param [in] sl is typically the number of components */ template void MemArray::reprZip(int sl, std::ostream& stream) const @@ -171,8 +241,8 @@ namespace ParaMEDMEM { if(_nb_of_elem!=0 && sl!=0) { - int nbOfTuples=_nb_of_elem/sl; - for(int i=0;i(stream," ")); @@ -187,36 +257,40 @@ namespace ParaMEDMEM else stream << "No data !\n"; } - + template void MemArray::fillWithValue(const T& val) { T *pt=_pointer.getPointer(); std::fill(pt,pt+_nb_of_elem,val); } - + template T *MemArray::fromNoInterlace(int nbOfComp) const { + if(nbOfComp<1) + throw INTERP_KERNEL::Exception("MemArray::fromNoInterlace : number of components must be > 0 !"); const T *pt=_pointer.getConstPointer(); - int nbOfTuples=_nb_of_elem/nbOfComp; - T *ret=new T[_nb_of_elem]; + std::size_t nbOfTuples=_nb_of_elem/nbOfComp; + T *ret=(T*)malloc(_nb_of_elem*sizeof(T)); T *w=ret; - for(int i=0;i T *MemArray::toNoInterlace(int nbOfComp) const { + if(nbOfComp<1) + throw INTERP_KERNEL::Exception("MemArray::toNoInterlace : number of components must be > 0 !"); const T *pt=_pointer.getConstPointer(); - int nbOfTuples=_nb_of_elem/nbOfComp; - T *ret=new T[_nb_of_elem]; + std::size_t nbOfTuples=_nb_of_elem/nbOfComp; + T *ret=(T*)malloc(_nb_of_elem*sizeof(T)); T *w=ret; for(int i=0;i - void MemArray::reverse() + void MemArray::reverse(int nbOfComp) { + if(nbOfComp<1) + throw INTERP_KERNEL::Exception("MemArray::reverse : only supported with 'this' array with ONE or more than ONE component !"); T *pt=_pointer.getPointer(); - std::reverse(pt,pt+_nb_of_elem); + if(nbOfComp==1) + { + std::reverse(pt,pt+_nb_of_elem); + return ; + } + else + { + T *pt2=pt+_nb_of_elem-nbOfComp; + std::size_t nbOfTuples=_nb_of_elem/nbOfComp; + for(std::size_t i=0;i - void MemArray::alloc(int nbOfElements) throw(INTERP_KERNEL::Exception) + void MemArray::alloc(std::size_t nbOfElements) { destroy(); - if(nbOfElements<0) - throw INTERP_KERNEL::Exception("MemArray::alloc : request for negative length of data !"); _nb_of_elem=nbOfElements; - _pointer.setInternal(new T[_nb_of_elem]); + _nb_of_elem_alloc=nbOfElements; + _pointer.setInternal((T*)malloc(_nb_of_elem_alloc*sizeof(T))); _ownership=true; - _dealloc=CPP_DEALLOC; + _dealloc=CDeallocator; } - + + /*! + * This method performs systematically an allocation of \a newNbOfElements elements in \a this. + * \a _nb_of_elem and \a _nb_of_elem_alloc will \b NOT be systematically equal (contrary to MemArray::reAlloc method. + * So after the call of this method \a _nb_of_elem will be equal tostd::min(_nb_of_elem,newNbOfElements) and \a _nb_of_elem_alloc equal to + * \a newNbOfElements. This method is typically used to perform a pushBack to avoid systematic allocations-copy-deallocation. + * So after the call of this method the accessible content is perfectly set. + * + * So this method should not be confused with MemArray::reserve that is close to MemArray::reAlloc but not same. + */ template - void MemArray::reAlloc(int newNbOfElements) throw(INTERP_KERNEL::Exception) + void MemArray::reserve(std::size_t newNbOfElements) { - if(newNbOfElements<0) - throw INTERP_KERNEL::Exception("MemArray::reAlloc : request for negative length of data !"); - T *pointer=new T[newNbOfElements]; - std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min(_nb_of_elem,newNbOfElements),pointer); + if(_nb_of_elem_alloc==newNbOfElements) + return ; + T *pointer=(T*)malloc(newNbOfElements*sizeof(T)); + std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min(_nb_of_elem,newNbOfElements),pointer); if(_ownership) - destroyPointer(const_cast(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external + DestroyPointer(const_cast(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external + _pointer.setInternal(pointer); + _nb_of_elem=std::min(_nb_of_elem,newNbOfElements); + _nb_of_elem_alloc=newNbOfElements; + _ownership=true; + _dealloc=CDeallocator; + _param_for_deallocator=0; + } + + /*! + * This method performs systematically an allocation of \a newNbOfElements elements in \a this. + * \a _nb_of_elem and \a _nb_of_elem_alloc will be equal even if only std::min(_nb_of_elem,newNbOfElements) come from the . + * The remaing part of the new allocated chunk are available but not set previouly ! + * + * So this method should not be confused with MemArray::reserve that is close to MemArray::reAlloc but not same. + */ + template + void MemArray::reAlloc(std::size_t newNbOfElements) + { + if(_nb_of_elem==newNbOfElements) + return ; + T *pointer=(T*)malloc(newNbOfElements*sizeof(T)); + std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min(_nb_of_elem,newNbOfElements),pointer); + if(_ownership) + DestroyPointer(const_cast(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external _pointer.setInternal(pointer); _nb_of_elem=newNbOfElements; + _nb_of_elem_alloc=newNbOfElements; _ownership=true; - _dealloc=CPP_DEALLOC; + _dealloc=CDeallocator; + _param_for_deallocator=0; + } + + template + void MemArray::CPPDeallocator(void *pt, void *param) + { + delete [] reinterpret_cast(pt); + } + + template + void MemArray::CDeallocator(void *pt, void *param) + { + free(pt); } template - void MemArray::destroyPointer(T *pt, DeallocType type) + typename MemArray::Deallocator MemArray::BuildFromType(DeallocType type) { switch(type) - { + { case CPP_DEALLOC: - { - delete [] pt; - return ; - } + return CPPDeallocator; case C_DEALLOC: - { - free(pt); - return ; - } + return CDeallocator; default: - std::ostringstream stream; - stream << "Invalid deallocation requested for pointer " << pt; - throw INTERP_KERNEL::Exception(stream.str().c_str()); - } + throw INTERP_KERNEL::Exception("Invalid deallocation requested ! Unrecognized enum DeallocType !"); + } + } + + template + void MemArray::DestroyPointer(T *pt, typename MemArray::Deallocator dealloc, void *param) + { + if(dealloc) + dealloc(pt,param); } template void MemArray::destroy() { if(_ownership) - destroyPointer(const_cast(_pointer.getConstPointer()),_dealloc);//Do not use getPointer because in case of _external + DestroyPointer(const_cast(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external _pointer.null(); _ownership=false; + _dealloc=NULL; + _param_for_deallocator=NULL; + _nb_of_elem=0; + _nb_of_elem_alloc=0; } - + template MemArray &MemArray::operator=(const MemArray& other) {