]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Code factorization in DataArrays
authorAnthony Geay <anthony.geay@edf.fr>
Fri, 19 Aug 2016 09:42:32 +0000 (11:42 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Fri, 19 Aug 2016 09:42:32 +0000 (11:42 +0200)
src/MEDCoupling/CMakeLists.txt
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingMemArray.txx
src/MEDCoupling/MEDCouplingMemArrayChar.cxx
src/MEDCoupling/MEDCouplingTraits.cxx [new file with mode: 0644]
src/MEDCoupling/MEDCouplingTraits.hxx [new file with mode: 0644]
src/MEDCoupling_Swig/MEDCouplingMemArray.i

index 826cbc6dff7805fc61fc4717a21506cddb23b2d1..3a70181ea79d342a37ace48693ff5541a47a36c2 100644 (file)
@@ -40,6 +40,7 @@ SET(medcoupling_SOURCES
   MEDCoupling1GTUMesh.cxx
   MEDCouplingMemArray.cxx
   MEDCouplingMemArrayChar.cxx
+  MEDCouplingTraits.cxx
   MEDCouplingTimeLabel.cxx
   MEDCouplingCMesh.cxx
   MEDCouplingIMesh.cxx
index 28806d19d08a755c9ca918e3c3d427940c22decf..8459ce8fe5dfac6a83b8e40f4f9c6fd73227f62f 100644 (file)
@@ -37,6 +37,9 @@ typedef double (*MYFUNCPTR)(double);
 
 using namespace MEDCoupling;
 
+template class DataArrayTemplate<int>;
+template class DataArrayTemplate<double>;
+
 template<int SPACEDIM>
 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
 {
@@ -750,43 +753,6 @@ DataArrayDouble *DataArrayDouble::New()
   return new DataArrayDouble;
 }
 
-/*!
- * Checks if raw data is allocated. Read more on the raw data
- * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
- *  \return bool - \a true if the raw data is allocated, \a false else.
- */
-bool DataArrayDouble::isAllocated() const
-{
-  return getConstPointer()!=0;
-}
-
-/*!
- * Checks if raw data is allocated and throws an exception if it is not the case.
- *  \throw If the raw data is not allocated.
- */
-void DataArrayDouble::checkAllocated() const
-{
-  if(!isAllocated())
-    throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
-}
-
-/*!
- * This method desallocated \a this without modification of informations relative to the components.
- * After call of this method, DataArrayDouble::isAllocated will return false.
- * If \a this is already not allocated, \a this is let unchanged.
- */
-void DataArrayDouble::desallocate()
-{
-  _mem.destroy();
-}
-
-std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const
-{
-  std::size_t sz(_mem.getNbOfElemAllocated());
-  sz*=sizeof(double);
-  return DataArray::getHeapMemorySizeWithoutChildren()+sz;
-}
-
 /*!
  * Returns the only one value in \a this, if and only if number of elements
  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
@@ -808,17 +774,6 @@ double DataArrayDouble::doubleValue() const
     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
 }
 
-/*!
- * Checks the number of tuples.
- *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
- *  \throw If \a this is not allocated.
- */
-bool DataArrayDouble::empty() const
-{
-  checkAllocated();
-  return getNumberOfTuples()==0;
-}
-
 /*!
  * Returns a full copy of \a this. For more info on copying data arrays see
  * \ref MEDCouplingArrayBasicsCopyDeep.
@@ -848,154 +803,6 @@ DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
     }
 }
 
-/*!
- * Copies all the data from another DataArrayDouble. For more info see
- * \ref MEDCouplingArrayBasicsCopyDeepAssign.
- *  \param [in] other - another instance of DataArrayDouble to copy data from.
- *  \throw If the \a other is not allocated.
- */
-void DataArrayDouble::deepCopyFrom(const DataArrayDouble& other)
-{
-  other.checkAllocated();
-  int nbOfTuples=other.getNumberOfTuples();
-  int nbOfComp=other.getNumberOfComponents();
-  allocIfNecessary(nbOfTuples,nbOfComp);
-  std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
-  double *pt=getPointer();
-  const double *ptI=other.getConstPointer();
-  for(std::size_t i=0;i<nbOfElems;i++)
-    pt[i]=ptI[i];
-  copyStringInfoFrom(other);
-}
-
-/*!
- * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
- * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
- * If \a this has not already been allocated, number of components is set to one.
- * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
- * 
- * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
- */
-void DataArrayDouble::reserve(std::size_t nbOfElems)
-{
-  int nbCompo=getNumberOfComponents();
-  if(nbCompo==1)
-    {
-      _mem.reserve(nbOfElems);
-    }
-  else if(nbCompo==0)
-    {
-      _mem.reserve(nbOfElems);
-      _info_on_compo.resize(1);
-    }
-  else
-    throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
-}
-
-/*!
- * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
- * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
- *
- * \param [in] val the value to be added in \a this
- * \throw If \a this has already been allocated with number of components different from one.
- * \sa DataArrayDouble::pushBackValsSilent
- */
-void DataArrayDouble::pushBackSilent(double val)
-{
-  int nbCompo=getNumberOfComponents();
-  if(nbCompo==1)
-    _mem.pushBack(val);
-  else if(nbCompo==0)
-    {
-      _info_on_compo.resize(1);
-      _mem.pushBack(val);
-    }
-  else
-    throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
-}
-
-/*!
- * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
- * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
- *
- *  \param [in] valsBg - an array of values to push at the end of \c this.
- *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
- *              the last value of \a valsBg is \a valsEnd[ -1 ].
- * \throw If \a this has already been allocated with number of components different from one.
- * \sa DataArrayDouble::pushBackSilent
- */
-void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd)
-{
-  int nbCompo=getNumberOfComponents();
-  if(nbCompo==1)
-    _mem.insertAtTheEnd(valsBg,valsEnd);
-  else if(nbCompo==0)
-    {
-      _info_on_compo.resize(1);
-      _mem.insertAtTheEnd(valsBg,valsEnd);
-    }
-  else
-    throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
-}
-
-/*!
- * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
- * \throw If \a this is already empty.
- * \throw If \a this has number of components different from one.
- */
-double DataArrayDouble::popBackSilent()
-{
-  if(getNumberOfComponents()==1)
-    return _mem.popBack();
-  else
-    throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
-}
-
-/*!
- * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
- *
- * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve
- */
-void DataArrayDouble::pack() const
-{
-  _mem.pack();
-}
-
-/*!
- * Allocates the raw data in memory. If exactly same memory as needed already
- * allocated, it is not re-allocated.
- *  \param [in] nbOfTuple - number of tuples of data to allocate.
- *  \param [in] nbOfCompo - number of components of data to allocate.
- *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
- */
-void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
-{
-  if(isAllocated())
-    {
-      if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
-        alloc(nbOfTuple,nbOfCompo);
-    }
-  else
-    alloc(nbOfTuple,nbOfCompo);
-}
-
-/*!
- * Allocates the raw data in memory. If the memory was already allocated, then it is
- * freed and re-allocated. See an example of this method use
- * \ref MEDCouplingArraySteps1WC "here".
- *  \param [in] nbOfTuple - number of tuples of data to allocate.
- *  \param [in] nbOfCompo - number of components of data to allocate.
- *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
- */
-void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
-{
-  if(nbOfTuple<0 || nbOfCompo<0)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
-  _info_on_compo.resize(nbOfCompo);
-  _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
-  declareAsNew();
-}
-
 /*!
  * Assign zero to all values in \a this array. To know more on filling arrays see
  * \ref MEDCouplingArrayFill.
@@ -1003,22 +810,7 @@ void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo)
  */
 void DataArrayDouble::fillWithZero()
 {
-  checkAllocated();
-  _mem.fillWithValue(0.);
-  declareAsNew();
-}
-
-/*!
- * Assign \a val to all values in \a this array. To know more on filling arrays see
- * \ref MEDCouplingArrayFill.
- *  \param [in] val - the value to fill with.
- *  \throw If \a this is not allocated.
- */
-void DataArrayDouble::fillWithValue(double val)
-{
-  checkAllocated();
-  _mem.fillWithValue(val);
-  declareAsNew();
+  fillWithValue(0.);
 }
 
 /*!
@@ -1065,33 +857,6 @@ bool DataArrayDouble::isUniform(double val, double eps) const
   return true;
 }
 
-/*!
- * Sorts values of the array.
- *  \param [in] asc - \a true means ascending order, \a false, descending.
- *  \throw If \a this is not allocated.
- *  \throw If \a this->getNumberOfComponents() != 1.
- */
-void DataArrayDouble::sort(bool asc)
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::sort : only supported with 'this' array with ONE component !");
-  _mem.sort(asc);
-  declareAsNew();
-}
-
-/*!
- * Reverse the array values.
- *  \throw If \a this->getNumberOfComponents() < 1.
- *  \throw If \a this is not allocated.
- */
-void DataArrayDouble::reverse()
-{
-  checkAllocated();
-  _mem.reverse(getNumberOfComponents());
-  declareAsNew();
-}
-
 /*!
  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
  * with at least absolute difference value of |\a eps| at each step.
@@ -1386,22 +1151,6 @@ bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other,
   return _mem.isEqual(other._mem,prec,tmp);
 }
 
-/*!
- * Changes number of tuples in the array. If the new number of tuples is smaller
- * than the current number the array is truncated, otherwise the array is extended.
- *  \param [in] nbOfTuples - new number of tuples. 
- *  \throw If \a this is not allocated.
- *  \throw If \a nbOfTuples is negative.
- */
-void DataArrayDouble::reAlloc(int nbOfTuples)
-{
-  if(nbOfTuples<0)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
-  checkAllocated();
-  _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
-  declareAsNew();
-}
-
 /*!
  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
  * array to the new one.
@@ -1459,99 +1208,6 @@ DataArrayDouble *DataArrayDouble::toNoInterlace() const
   return ret;
 }
 
-/*!
- * Permutes values of \a this array as required by \a old2New array. The values are
- * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
- * the same as in \c this one.
- * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
- * For more info on renumbering see \ref numbering.
- *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
- *     giving a new position for i-th old value.
- */
-void DataArrayDouble::renumberInPlace(const int *old2New)
-{
-  checkAllocated();
-  int nbTuples=getNumberOfTuples();
-  int nbOfCompo=getNumberOfComponents();
-  double *tmp=new double[nbTuples*nbOfCompo];
-  const double *iptr=getConstPointer();
-  for(int i=0;i<nbTuples;i++)
-    {
-      int v=old2New[i];
-      if(v>=0 && v<nbTuples)
-        std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
-  delete [] tmp;
-  declareAsNew();
-}
-
-/*!
- * Permutes values of \a this array as required by \a new2Old array. The values are
- * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
- * the same as in \c this one.
- * For more info on renumbering see \ref numbering.
- *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
- *     giving a previous position of i-th new value.
- *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
- *          is to delete using decrRef() as it is no more needed.
- */
-void DataArrayDouble::renumberInPlaceR(const int *new2Old)
-{
-  checkAllocated();
-  int nbTuples=getNumberOfTuples();
-  int nbOfCompo=getNumberOfComponents();
-  double *tmp=new double[nbTuples*nbOfCompo];
-  const double *iptr=getConstPointer();
-  for(int i=0;i<nbTuples;i++)
-    {
-      int v=new2Old[i];
-      if(v>=0 && v<nbTuples)
-        std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
-  delete [] tmp;
-  declareAsNew();
-}
-
-/*!
- * Returns a copy of \a this array with values permuted as required by \a old2New array.
- * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
- * Number of tuples in the result array remains the same as in \c this one.
- * If a permutation reduction is needed, renumberAndReduce() should be used.
- * For more info on renumbering see \ref numbering.
- *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
- *          giving a new position for i-th old value.
- *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
- *          is to delete using decrRef() as it is no more needed.
- *  \throw If \a this is not allocated.
- */
-DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
-{
-  checkAllocated();
-  int nbTuples=getNumberOfTuples();
-  int nbOfCompo=getNumberOfComponents();
-  MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
-  ret->alloc(nbTuples,nbOfCompo);
-  ret->copyStringInfoFrom(*this);
-  const double *iptr=getConstPointer();
-  double *optr=ret->getPointer();
-  for(int i=0;i<nbTuples;i++)
-    std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
-  ret->copyStringInfoFrom(*this);
-  return ret.retn();
-}
-
 /*!
  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
@@ -2959,34 +2615,6 @@ void DataArrayDouble::setContigPartOfSelectedValuesSlice(int tupleIdStart, const
     }
 }
 
-/*!
- * Returns a value located at specified tuple and component.
- * This method is equivalent to DataArrayDouble::getIJ() except that validity of
- * parameters is checked. So this method is safe but expensive if used to go through
- * all values of \a this.
- *  \param [in] tupleId - index of tuple of interest.
- *  \param [in] compoId - index of component of interest.
- *  \return double - value located by \a tupleId and \a compoId.
- *  \throw If \a this is not allocated.
- *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
- *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
- */
-double DataArrayDouble::getIJSafe(int tupleId, int compoId) const
-{
-  checkAllocated();
-  if(tupleId<0 || tupleId>=getNumberOfTuples())
-    {
-      std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  if(compoId<0 || compoId>=getNumberOfComponents())
-    {
-      std::ostringstream oss; oss << "DataArrayDouble::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  return _mem[tupleId*_info_on_compo.size()+compoId];
-}
-
 /*!
  * Returns the first value of \a this. 
  *  \return double - the last value of \a this array.
@@ -3035,32 +2663,6 @@ void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &ar
     }
 }
 
-/*!
- * Sets a C array to be used as raw data of \a this. The previously set info
- *  of components is retained and re-sized. 
- * For more info see \ref MEDCouplingArraySteps1.
- *  \param [in] array - the C array to be used as raw data of \a this.
- *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
- *  \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
- *                     \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
- *                     \c free(\c array ) will be called.
- *  \param [in] nbOfTuple - new number of tuples in \a this.
- *  \param [in] nbOfCompo - new number of components in \a this.
- */
-void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
-{
-  _info_on_compo.resize(nbOfCompo);
-  _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
-  declareAsNew();
-}
-
-void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
-{
-  _info_on_compo.resize(nbOfCompo);
-  _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
-  declareAsNew();
-}
-
 void DataArrayDouble::aggregate(const DataArrayDouble *other)
 {
   if(!other)
@@ -5981,43 +5583,6 @@ DataArrayInt *DataArrayInt::New()
   return new DataArrayInt;
 }
 
-/*!
- * Checks if raw data is allocated. Read more on the raw data
- * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
- *  \return bool - \a true if the raw data is allocated, \a false else.
- */
-bool DataArrayInt::isAllocated() const
-{
-  return getConstPointer()!=0;
-}
-
-/*!
- * Checks if raw data is allocated and throws an exception if it is not the case.
- *  \throw If the raw data is not allocated.
- */
-void DataArrayInt::checkAllocated() const
-{
-  if(!isAllocated())
-    throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
-}
-
-/*!
- * This method desallocated \a this without modification of informations relative to the components.
- * After call of this method, DataArrayInt::isAllocated will return false.
- * If \a this is already not allocated, \a this is let unchanged.
- */
-void DataArrayInt::desallocate()
-{
-  _mem.destroy();
-}
-
-std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const
-{
-  std::size_t sz(_mem.getNbOfElemAllocated());
-  sz*=sizeof(int);
-  return DataArray::getHeapMemorySizeWithoutChildren()+sz;
-}
-
 /*!
  * Returns the only one value in \a this, if and only if number of elements
  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
@@ -6060,17 +5625,6 @@ int DataArrayInt::getHashCode() const
   return ret+ret0;
 }
 
-/*!
- * Checks the number of tuples.
- *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
- *  \throw If \a this is not allocated.
- */
-bool DataArrayInt::empty() const
-{
-  checkAllocated();
-  return getNumberOfTuples()==0;
-}
-
 /*!
  * Returns a full copy of \a this. For more info on copying data arrays see
  * \ref MEDCouplingArrayBasicsCopyDeep.
@@ -6099,154 +5653,6 @@ DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
     }
 }
 
-/*!
- * Copies all the data from another DataArrayInt. For more info see
- * \ref MEDCouplingArrayBasicsCopyDeepAssign.
- *  \param [in] other - another instance of DataArrayInt to copy data from.
- *  \throw If the \a other is not allocated.
- */
-void DataArrayInt::deepCopyFrom(const DataArrayInt& other)
-{
-  other.checkAllocated();
-  int nbOfTuples=other.getNumberOfTuples();
-  int nbOfComp=other.getNumberOfComponents();
-  allocIfNecessary(nbOfTuples,nbOfComp);
-  std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
-  int *pt=getPointer();
-  const int *ptI=other.getConstPointer();
-  for(std::size_t i=0;i<nbOfElems;i++)
-    pt[i]=ptI[i];
-  copyStringInfoFrom(other);
-}
-
-/*!
- * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
- * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
- * If \a this has not already been allocated, number of components is set to one.
- * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this.
- * 
- * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent
- */
-void DataArrayInt::reserve(std::size_t nbOfElems)
-{
-  int nbCompo=getNumberOfComponents();
-  if(nbCompo==1)
-    {
-      _mem.reserve(nbOfElems);
-    }
-  else if(nbCompo==0)
-    {
-      _mem.reserve(nbOfElems);
-      _info_on_compo.resize(1);
-    }
-  else
-    throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
-}
-
-/*!
- * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
- * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
- *
- * \param [in] val the value to be added in \a this
- * \throw If \a this has already been allocated with number of components different from one.
- * \sa DataArrayInt::pushBackValsSilent
- */
-void DataArrayInt::pushBackSilent(int val)
-{
-  int nbCompo=getNumberOfComponents();
-  if(nbCompo==1)
-    _mem.pushBack(val);
-  else if(nbCompo==0)
-    {
-      _info_on_compo.resize(1);
-      _mem.pushBack(val);
-    }
-  else
-    throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
-}
-
-/*!
- * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
- * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
- *
- *  \param [in] valsBg - an array of values to push at the end of \c this.
- *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
- *              the last value of \a valsBg is \a valsEnd[ -1 ].
- * \throw If \a this has already been allocated with number of components different from one.
- * \sa DataArrayInt::pushBackSilent
- */
-void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd)
-{
-  int nbCompo=getNumberOfComponents();
-  if(nbCompo==1)
-    _mem.insertAtTheEnd(valsBg,valsEnd);
-  else if(nbCompo==0)
-    {
-      _info_on_compo.resize(1);
-      _mem.insertAtTheEnd(valsBg,valsEnd);
-    }
-  else
-    throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
-}
-
-/*!
- * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
- * \throw If \a this is already empty.
- * \throw If \a this has number of components different from one.
- */
-int DataArrayInt::popBackSilent()
-{
-  if(getNumberOfComponents()==1)
-    return _mem.popBack();
-  else
-    throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
-}
-
-/*!
- * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
- *
- * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve
- */
-void DataArrayInt::pack() const
-{
-  _mem.pack();
-}
-
-/*!
- * Allocates the raw data in memory. If exactly as same memory as needed already
- * allocated, it is not re-allocated.
- *  \param [in] nbOfTuple - number of tuples of data to allocate.
- *  \param [in] nbOfCompo - number of components of data to allocate.
- *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
- */
-void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
-{
-  if(isAllocated())
-    {
-      if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
-        alloc(nbOfTuple,nbOfCompo);
-    }
-  else
-    alloc(nbOfTuple,nbOfCompo);
-}
-
-/*!
- * Allocates the raw data in memory. If the memory was already allocated, then it is
- * freed and re-allocated. See an example of this method use
- * \ref MEDCouplingArraySteps1WC "here".
- *  \param [in] nbOfTuple - number of tuples of data to allocate.
- *  \param [in] nbOfCompo - number of components of data to allocate.
- *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
- */
-void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
-{
-  if(nbOfTuple<0 || nbOfCompo<0)
-    throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
-  _info_on_compo.resize(nbOfCompo);
-  _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
-  declareAsNew();
-}
-
 /*!
  * Assign zero to all values in \a this array. To know more on filling arrays see
  * \ref MEDCouplingArrayFill.
@@ -6254,22 +5660,7 @@ void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo)
  */
 void DataArrayInt::fillWithZero()
 {
-  checkAllocated();
-  _mem.fillWithValue(0);
-  declareAsNew();
-}
-
-/*!
- * Assign \a val to all values in \a this array. To know more on filling arrays see
- * \ref MEDCouplingArrayFill.
- *  \param [in] val - the value to fill with.
- *  \throw If \a this is not allocated.
- */
-void DataArrayInt::fillWithValue(int val)
-{
-  checkAllocated();
-  _mem.fillWithValue(val);
-  declareAsNew();
+  fillWithValue(0);
 }
 
 /*!
@@ -6954,21 +6345,6 @@ void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) cons
       vec[i]=true;
 }
 
-/*!
- * Sorts values of the array.
- *  \param [in] asc - \a true means ascending order, \a false, descending.
- *  \throw If \a this is not allocated.
- *  \throw If \a this->getNumberOfComponents() != 1.
- */
-void DataArrayInt::sort(bool asc)
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !");
-  _mem.sort(asc);
-  declareAsNew();
-}
-
 /*!
  * Computes for each tuple the sum of number of components values in the tuple and return it.
  * 
@@ -6991,18 +6367,6 @@ DataArrayInt *DataArrayInt::sumPerTuple() const
   return ret.retn();
 }
 
-/*!
- * Reverse the array values.
- *  \throw If \a this->getNumberOfComponents() < 1.
- *  \throw If \a this is not allocated.
- */
-void DataArrayInt::reverse()
-{
-  checkAllocated();
-  _mem.reverse(getNumberOfComponents());
-  declareAsNew();
-}
-
 /*!
  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
  * If not an exception is thrown.
@@ -7165,32 +6529,6 @@ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
   return ret.retn();
 }
 
-/*!
- * Sets a C array to be used as raw data of \a this. The previously set info
- *  of components is retained and re-sized. 
- * For more info see \ref MEDCouplingArraySteps1.
- *  \param [in] array - the C array to be used as raw data of \a this.
- *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
- *  \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
- *                     \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
- *                     \c free(\c array ) will be called.
- *  \param [in] nbOfTuple - new number of tuples in \a this.
- *  \param [in] nbOfCompo - new number of components in \a this.
- */
-void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
-{
-  _info_on_compo.resize(nbOfCompo);
-  _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
-  declareAsNew();
-}
-
-void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
-{
-  _info_on_compo.resize(nbOfCompo);
-  _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
-  declareAsNew();
-}
-
 void DataArrayInt::aggregate(const DataArrayInt *other)
 {
   if(!other)
@@ -7242,99 +6580,6 @@ DataArrayInt *DataArrayInt::toNoInterlace() const
   return ret;
 }
 
-/*!
- * Permutes values of \a this array as required by \a old2New array. The values are
- * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
- * the same as in \c this one.
- * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
- * For more info on renumbering see \ref numbering.
- *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
- *     giving a new position for i-th old value.
- */
-void DataArrayInt::renumberInPlace(const int *old2New)
-{
-  checkAllocated();
-  int nbTuples=getNumberOfTuples();
-  int nbOfCompo=getNumberOfComponents();
-  int *tmp=new int[nbTuples*nbOfCompo];
-  const int *iptr=getConstPointer();
-  for(int i=0;i<nbTuples;i++)
-    {
-      int v=old2New[i];
-      if(v>=0 && v<nbTuples)
-        std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
-  delete [] tmp;
-  declareAsNew();
-}
-
-/*!
- * Permutes values of \a this array as required by \a new2Old array. The values are
- * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
- * the same as in \c this one.
- * For more info on renumbering see \ref numbering.
- *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
- *     giving a previous position of i-th new value.
- *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
- *          is to delete using decrRef() as it is no more needed.
- */
-void DataArrayInt::renumberInPlaceR(const int *new2Old)
-{
-  checkAllocated();
-  int nbTuples=getNumberOfTuples();
-  int nbOfCompo=getNumberOfComponents();
-  int *tmp=new int[nbTuples*nbOfCompo];
-  const int *iptr=getConstPointer();
-  for(int i=0;i<nbTuples;i++)
-    {
-      int v=new2Old[i];
-      if(v>=0 && v<nbTuples)
-        std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
-  delete [] tmp;
-  declareAsNew();
-}
-
-/*!
- * Returns a copy of \a this array with values permuted as required by \a old2New array.
- * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
- * Number of tuples in the result array remains the same as in \c this one.
- * If a permutation reduction is needed, renumberAndReduce() should be used.
- * For more info on renumbering see \ref numbering.
- *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
- *          giving a new position for i-th old value.
- *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
- *          is to delete using decrRef() as it is no more needed.
- *  \throw If \a this is not allocated.
- */
-DataArrayInt *DataArrayInt::renumber(const int *old2New) const
-{
-  checkAllocated();
-  int nbTuples=getNumberOfTuples();
-  int nbOfCompo=getNumberOfComponents();
-  MCAuto<DataArrayInt> ret=DataArrayInt::New();
-  ret->alloc(nbTuples,nbOfCompo);
-  ret->copyStringInfoFrom(*this);
-  const int *iptr=getConstPointer();
-  int *optr=ret->getPointer();
-  for(int i=0;i<nbTuples;i++)
-    std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
-  ret->copyStringInfoFrom(*this);
-  return ret.retn();
-}
-
 /*!
  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
@@ -8017,23 +7262,6 @@ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue)
   return ret.retn();
 }
 
-/*!
- * Changes number of tuples in the array. If the new number of tuples is smaller
- * than the current number the array is truncated, otherwise the array is extended.
- *  \param [in] nbOfTuples - new number of tuples. 
- *  \throw If \a this is not allocated.
- *  \throw If \a nbOfTuples is negative.
- */
-void DataArrayInt::reAlloc(int nbOfTuples)
-{
-  if(nbOfTuples<0)
-    throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
-  checkAllocated();
-  _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
-  declareAsNew();
-}
-
-
 /*!
  * Returns a copy of \a this array composed of selected components.
  * The new DataArrayInt has the same number of tuples but includes components
@@ -8760,34 +7988,6 @@ void DataArrayInt::setContigPartOfSelectedValuesSlice(int tupleIdStart, const Da
     }
 }
 
-/*!
- * Returns a value located at specified tuple and component.
- * This method is equivalent to DataArrayInt::getIJ() except that validity of
- * parameters is checked. So this method is safe but expensive if used to go through
- * all values of \a this.
- *  \param [in] tupleId - index of tuple of interest.
- *  \param [in] compoId - index of component of interest.
- *  \return double - value located by \a tupleId and \a compoId.
- *  \throw If \a this is not allocated.
- *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
- *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
- */
-int DataArrayInt::getIJSafe(int tupleId, int compoId) const
-{
-  checkAllocated();
-  if(tupleId<0 || tupleId>=getNumberOfTuples())
-    {
-      std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  if(compoId<0 || compoId>=getNumberOfComponents())
-    {
-      std::ostringstream oss; oss << "DataArrayInt::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  return _mem[tupleId*_info_on_compo.size()+compoId];
-}
-
 /*!
  * Returns the first value of \a this. 
  *  \return int - the last value of \a this array.
index 4f1a3d421d4575054076383df6f18a9d2c3aacf7..f83539808b208eedd514e06c1ad8247ddafc0d4e 100644 (file)
@@ -25,6 +25,7 @@
 #include "MEDCouplingTimeLabel.hxx"
 #include "MEDCouplingRefCountObject.hxx"
 #include "InterpKernelException.hxx"
+#include "MEDCouplingTraits.hxx"
 #include "BBTreePts.txx"
 
 #include <string>
@@ -147,6 +148,7 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT int getNumberOfComponents() const { return (int)_info_on_compo.size(); }
     MEDCOUPLING_EXPORT void setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true);
     MEDCOUPLING_EXPORT virtual DataArray *deepCopy() const = 0;
+    MEDCOUPLING_EXPORT virtual DataArray *buildNewEmptyInstance() const = 0;
     MEDCOUPLING_EXPORT virtual bool isAllocated() const = 0;
     MEDCOUPLING_EXPORT virtual void checkAllocated() const = 0;
     MEDCOUPLING_EXPORT virtual void desallocate() = 0;
@@ -199,41 +201,68 @@ namespace MEDCoupling
   };
 }
 
+namespace MEDCoupling
+{
+  template<class T>
+  class DataArrayTemplate : public DataArray
+  {
+  public:
+    MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
+    //
+    MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); }
+    MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); }
+    MEDCOUPLING_EXPORT bool empty() const;
+    MEDCOUPLING_EXPORT const T *getConstPointer() const { return _mem.getConstPointer(); }
+    MEDCOUPLING_EXPORT const T *begin() const { return getConstPointer(); }
+    MEDCOUPLING_EXPORT const T *end() const { return getConstPointer()+getNbOfElems(); }
+    MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1);
+    MEDCOUPLING_EXPORT void useArray(const T *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
+    MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const T *array, int nbOfTuple, int nbOfCompo);
+    MEDCOUPLING_EXPORT T getIJSafe(int tupleId, int compoId) const;
+    MEDCOUPLING_EXPORT T getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; }
+    MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, T newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); }
+    MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, T newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; }
+    MEDCOUPLING_EXPORT T *getPointer() { return _mem.getPointer(); declareAsNew(); }
+    MEDCOUPLING_EXPORT void pack() const;
+    MEDCOUPLING_EXPORT bool isAllocated() const;
+    MEDCOUPLING_EXPORT void checkAllocated() const;
+    MEDCOUPLING_EXPORT void desallocate();
+    MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems);
+    MEDCOUPLING_EXPORT void pushBackSilent(T val);
+    MEDCOUPLING_EXPORT void pushBackValsSilent(const T *valsBg, const T *valsEnd);
+    MEDCOUPLING_EXPORT T popBackSilent();
+    MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); }
+    MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo);
+    MEDCOUPLING_EXPORT void deepCopyFrom(const DataArrayTemplate<T>& other);
+    MEDCOUPLING_EXPORT void reverse();
+    MEDCOUPLING_EXPORT void fillWithValue(T val);
+    MEDCOUPLING_EXPORT void reAlloc(int newNbOfTuple);
+    MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New);
+    MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old);
+    MEDCOUPLING_EXPORT void sort(bool asc=true);
+    MEDCOUPLING_EXPORT typename Traits<T>::ArrayType *renumber(const int *old2New) const;
+  protected:
+    MemArray<T> _mem;
+  };
+}
+
 #include "MEDCouplingMemArray.txx"
 
 namespace MEDCoupling
 {
   class DataArrayInt;
   class DataArrayDoubleIterator;
-  class DataArrayDouble : public DataArray
+  class DataArrayDouble : public DataArrayTemplate<double>
   {
   public:
     MEDCOUPLING_EXPORT static DataArrayDouble *New();
-    MEDCOUPLING_EXPORT bool isAllocated() const;
-    MEDCOUPLING_EXPORT void checkAllocated() const;
-    MEDCOUPLING_EXPORT void desallocate();
-    MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); }
-    MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); }
-    MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
     MEDCOUPLING_EXPORT double doubleValue() const;
-    MEDCOUPLING_EXPORT bool empty() const;
     MEDCOUPLING_EXPORT DataArrayDouble *deepCopy() const;
+    MEDCOUPLING_EXPORT DataArrayDouble *buildNewEmptyInstance() const { return DataArrayDouble::New(); }
     MEDCOUPLING_EXPORT DataArrayDouble *performCopyOrIncrRef(bool deepCopy) const;
-    MEDCOUPLING_EXPORT void deepCopyFrom(const DataArrayDouble& other);
-    MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems);
-    MEDCOUPLING_EXPORT void pushBackSilent(double val);
-    MEDCOUPLING_EXPORT void pushBackValsSilent(const double *valsBg, const double *valsEnd);
-    MEDCOUPLING_EXPORT double popBackSilent();
-    MEDCOUPLING_EXPORT void pack() const;
-    MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); }
-    MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1);
-    MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT void fillWithZero();
-    MEDCOUPLING_EXPORT void fillWithValue(double val);
     MEDCOUPLING_EXPORT void iota(double init=0.);
     MEDCOUPLING_EXPORT bool isUniform(double val, double eps) const;
-    MEDCOUPLING_EXPORT void sort(bool asc=true);
-    MEDCOUPLING_EXPORT void reverse();
     MEDCOUPLING_EXPORT void checkMonotonic(bool increasing, double eps) const;
     MEDCOUPLING_EXPORT bool isMonotonic(bool increasing, double eps) const;
     MEDCOUPLING_EXPORT std::string repr() const;
@@ -252,13 +281,9 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT bool isEqual(const DataArrayDouble& other, double prec) const;
     MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const;
     MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const;
-    MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples);
     MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const;
     MEDCOUPLING_EXPORT DataArrayDouble *fromNoInterlace() const;
     MEDCOUPLING_EXPORT DataArrayDouble *toNoInterlace() const;
-    MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New);
-    MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old);
-    MEDCOUPLING_EXPORT DataArrayDouble *renumber(const int *old2New) const;
     MEDCOUPLING_EXPORT DataArrayDouble *renumberR(const int *new2Old) const;
     MEDCOUPLING_EXPORT DataArrayDouble *renumberAndReduce(const int *old2New, int newNbOfTuple) const;
     MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const;
@@ -292,20 +317,10 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec);
     MEDCOUPLING_EXPORT void setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step);
     MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); }
-    MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; }
     MEDCOUPLING_EXPORT double front() const;
     MEDCOUPLING_EXPORT double back() const;
-    MEDCOUPLING_EXPORT double getIJSafe(int tupleId, int compoId) const;
-    MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); }
-    MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; }
-    MEDCOUPLING_EXPORT double *getPointer() { return _mem.getPointer(); declareAsNew(); }
     MEDCOUPLING_EXPORT static void SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet);
-    MEDCOUPLING_EXPORT const double *getConstPointer() const { return _mem.getConstPointer(); }
     MEDCOUPLING_EXPORT DataArrayDoubleIterator *iterator();
-    MEDCOUPLING_EXPORT const double *begin() const { return getConstPointer(); }
-    MEDCOUPLING_EXPORT const double *end() const { return getConstPointer()+getNbOfElems(); }
-    MEDCOUPLING_EXPORT void useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
-    MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo);
     template<class InputIterator>
     void insertAtTheEnd(InputIterator first, InputIterator last);
     MEDCOUPLING_EXPORT void aggregate(const DataArrayDouble *other);
@@ -404,8 +419,6 @@ namespace MEDCoupling
   private:
     ~DataArrayDouble() { }
     DataArrayDouble() { }
-  private:
-    MemArray<double> _mem;
   };
 
   class DataArrayDoubleTuple;
@@ -441,30 +454,15 @@ namespace MEDCoupling
 
   class DataArrayIntIterator;
 
-  class DataArrayInt : public DataArray
+  class DataArrayInt : public DataArrayTemplate<int>
   {
   public:
     MEDCOUPLING_EXPORT static DataArrayInt *New();
-    MEDCOUPLING_EXPORT bool isAllocated() const;
-    MEDCOUPLING_EXPORT void checkAllocated() const;
-    MEDCOUPLING_EXPORT void desallocate();
-    MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); }
-    MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); }
-    MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
     MEDCOUPLING_EXPORT int intValue() const;
     MEDCOUPLING_EXPORT int getHashCode() const;
-    MEDCOUPLING_EXPORT bool empty() const;
     MEDCOUPLING_EXPORT DataArrayInt *deepCopy() const;
     MEDCOUPLING_EXPORT DataArrayInt *performCopyOrIncrRef(bool deepCopy) const;
-    MEDCOUPLING_EXPORT void deepCopyFrom(const DataArrayInt& other);
-    MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems);
-    MEDCOUPLING_EXPORT void pushBackSilent(int val);
-    MEDCOUPLING_EXPORT void pushBackValsSilent(const int *valsBg, const int *valsEnd);
-    MEDCOUPLING_EXPORT int popBackSilent();
-    MEDCOUPLING_EXPORT void pack() const;
-    MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); }
-    MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1);
-    MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo);
+    MEDCOUPLING_EXPORT DataArrayInt *buildNewEmptyInstance() const { return DataArrayInt::New(); }
     MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const;
     MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const;
     MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayInt& other) const;
@@ -474,14 +472,11 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT void switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const;
     MEDCOUPLING_EXPORT DataArrayInt *buildPermutationArr(const DataArrayInt& other) const;
     MEDCOUPLING_EXPORT DataArrayInt *sumPerTuple() const;
-    MEDCOUPLING_EXPORT void sort(bool asc=true);
-    MEDCOUPLING_EXPORT void reverse();
     MEDCOUPLING_EXPORT void checkMonotonic(bool increasing) const;
     MEDCOUPLING_EXPORT bool isMonotonic(bool increasing) const;
     MEDCOUPLING_EXPORT void checkStrictlyMonotonic(bool increasing) const;
     MEDCOUPLING_EXPORT bool isStrictlyMonotonic(bool increasing) const;
     MEDCOUPLING_EXPORT void fillWithZero();
-    MEDCOUPLING_EXPORT void fillWithValue(int val);
     MEDCOUPLING_EXPORT void iota(int init=0);
     MEDCOUPLING_EXPORT std::string repr() const;
     MEDCOUPLING_EXPORT std::string reprZip() const;
@@ -504,13 +499,9 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const;
     MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const;
     MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const;
-    MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples);
     MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const;
     MEDCOUPLING_EXPORT DataArrayInt *fromNoInterlace() const;
     MEDCOUPLING_EXPORT DataArrayInt *toNoInterlace() const;
-    MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New);
-    MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old);
-    MEDCOUPLING_EXPORT DataArrayInt *renumber(const int *old2New) const;
     MEDCOUPLING_EXPORT DataArrayInt *renumberR(const int *new2Old) const;
     MEDCOUPLING_EXPORT DataArrayInt *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const;
     MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const;
@@ -544,18 +535,10 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec);
     MEDCOUPLING_EXPORT void setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step);
     MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); }
-    MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; }
-    MEDCOUPLING_EXPORT int getIJSafe(int tupleId, int compoId) const;
     MEDCOUPLING_EXPORT int front() const;
     MEDCOUPLING_EXPORT int back() const;
-    MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); }
-    MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; }
-    MEDCOUPLING_EXPORT int *getPointer() { return _mem.getPointer(); declareAsNew(); }
     MEDCOUPLING_EXPORT static void SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet);
-    MEDCOUPLING_EXPORT const int *getConstPointer() const { return _mem.getConstPointer(); }
     MEDCOUPLING_EXPORT DataArrayIntIterator *iterator();
-    MEDCOUPLING_EXPORT const int *begin() const { return getConstPointer(); }
-    MEDCOUPLING_EXPORT const int *end() const { return getConstPointer()+getNbOfElems(); }
     MEDCOUPLING_EXPORT DataArrayInt *findIdsEqual(int val) const;
     MEDCOUPLING_EXPORT DataArrayInt *findIdsNotEqual(int val) const;
     MEDCOUPLING_EXPORT DataArrayInt *findIdsEqualList(const int *valsBg, const int *valsEnd) const;
@@ -624,8 +607,6 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT DataArrayInt *getDifferentValues() const;
     MEDCOUPLING_EXPORT std::vector<DataArrayInt *> partitionByDifferentValues(std::vector<int>& differentIds) const;
     MEDCOUPLING_EXPORT std::vector< std::pair<int,int> > splitInBalancedSlices(int nbOfSlices) const;
-    MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
-    MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo);
     template<class InputIterator>
     void insertAtTheEnd(InputIterator first, InputIterator last);
     MEDCOUPLING_EXPORT void aggregate(const DataArrayInt *other);
@@ -656,8 +637,6 @@ namespace MEDCoupling
   private:
     ~DataArrayInt() { }
     DataArrayInt() { }
-  private:
-    MemArray<int> _mem;
   };
 
   class DataArrayIntTuple;
@@ -691,40 +670,18 @@ namespace MEDCoupling
     int _nb_of_compo;
   };
 
-  class DataArrayChar : public DataArray
+  class DataArrayChar : public DataArrayTemplate<char>
   {
   public:
     MEDCOUPLING_EXPORT virtual DataArrayChar *buildEmptySpecializedDAChar() const = 0;
-    MEDCOUPLING_EXPORT bool isAllocated() const;
-    MEDCOUPLING_EXPORT void checkAllocated() const;
-    MEDCOUPLING_EXPORT void desallocate();
-    MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); }
-    MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); }
-    MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
     MEDCOUPLING_EXPORT int getHashCode() const;
-    MEDCOUPLING_EXPORT bool empty() const;
-    MEDCOUPLING_EXPORT void deepCopyFrom(const DataArrayChar& other);
-    MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems);
-    MEDCOUPLING_EXPORT void pushBackSilent(char val);
-    MEDCOUPLING_EXPORT void pushBackValsSilent(const char *valsBg, const char *valsEnd);
-    MEDCOUPLING_EXPORT char popBackSilent();
-    MEDCOUPLING_EXPORT void pack() const;
-    MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); }
-    MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1);
-    MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT bool isEqual(const DataArrayChar& other) const;
     MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const;
     MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayChar& other) const;
-    MEDCOUPLING_EXPORT void reverse();
     MEDCOUPLING_EXPORT void fillWithZero();
-    MEDCOUPLING_EXPORT void fillWithValue(char val);
     MEDCOUPLING_EXPORT std::string repr() const;
     MEDCOUPLING_EXPORT std::string reprZip() const;
-    MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples);
     MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const;
-    MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New);
-    MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old);
-    MEDCOUPLING_EXPORT DataArrayChar *renumber(const int *old2New) const;
     MEDCOUPLING_EXPORT DataArrayChar *renumberR(const int *new2Old) const;
     MEDCOUPLING_EXPORT DataArrayChar *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const;
     MEDCOUPLING_EXPORT DataArrayChar *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const;
@@ -749,16 +706,8 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT void setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step);
     MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const;
     MEDCOUPLING_EXPORT void getTuple(int tupleId, char *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); }
-    MEDCOUPLING_EXPORT char getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; }
-    MEDCOUPLING_EXPORT char getIJSafe(int tupleId, int compoId) const;
     MEDCOUPLING_EXPORT char front() const;
     MEDCOUPLING_EXPORT char back() const;
-    MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, char newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); }
-    MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, char newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; }
-    MEDCOUPLING_EXPORT char *getPointer() { return _mem.getPointer(); declareAsNew(); }
-    MEDCOUPLING_EXPORT const char *getConstPointer() const { return _mem.getConstPointer(); }
-    MEDCOUPLING_EXPORT const char *begin() const { return getConstPointer(); }
-    MEDCOUPLING_EXPORT const char *end() const { return getConstPointer()+getNbOfElems(); }
     MEDCOUPLING_EXPORT DataArrayInt *findIdsEqual(char val) const;
     MEDCOUPLING_EXPORT DataArrayInt *findIdsNotEqual(char val) const;
     MEDCOUPLING_EXPORT int findIdSequence(const std::vector<char>& vals) const;
@@ -777,10 +726,8 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT static DataArrayChar *Aggregate(const std::vector<const DataArrayChar *>& arr);
     MEDCOUPLING_EXPORT static DataArrayChar *Meld(const DataArrayChar *a1, const DataArrayChar *a2);
     MEDCOUPLING_EXPORT static DataArrayChar *Meld(const std::vector<const DataArrayChar *>& arr);
-    MEDCOUPLING_EXPORT void useArray(const char *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
     template<class InputIterator>
     void insertAtTheEnd(InputIterator first, InputIterator last);
-    MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const char *array, int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT void updateTime() const { }
     MEDCOUPLING_EXPORT MemArray<char>& accessToMemArray() { return _mem; }
     MEDCOUPLING_EXPORT const MemArray<char>& accessToMemArray() const { return _mem; }
@@ -791,8 +738,6 @@ namespace MEDCoupling
     //MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS);
   protected:
     DataArrayChar() { }
-  protected:
-    MemArray<char> _mem;
   };
 
   class DataArrayByteIterator;
@@ -805,6 +750,7 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT DataArrayByteIterator *iterator();
     MEDCOUPLING_EXPORT DataArrayByte *deepCopy() const;
     MEDCOUPLING_EXPORT DataArrayByte *performCopyOrIncrRef(bool deepCopy) const;
+    MEDCOUPLING_EXPORT DataArrayByte *buildNewEmptyInstance() const { return DataArrayByte::New(); }
     MEDCOUPLING_EXPORT char byteValue() const;
     MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const;
     MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const;
@@ -863,6 +809,7 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT DataArrayAsciiCharIterator *iterator();
     MEDCOUPLING_EXPORT DataArrayAsciiChar *deepCopy() const;
     MEDCOUPLING_EXPORT DataArrayAsciiChar *performCopyOrIncrRef(bool deepCopy) const;
+    MEDCOUPLING_EXPORT DataArrayAsciiChar *buildNewEmptyInstance() const { return DataArrayAsciiChar::New(); }
     MEDCOUPLING_EXPORT char asciiCharValue() const;
     MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const;
     MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const;
index a8e18cde6b9a76a39a3baf439db31b71b93923a9..52d50034074ddd33422bf58dd7809182b5c9d2b7 100644 (file)
@@ -25,6 +25,7 @@
 #include "NormalizedUnstructuredMesh.hxx"
 #include "InterpKernelException.hxx"
 #include "InterpolationUtils.hxx"
+#include "MCAuto.hxx"
 
 #include <sstream>
 #include <cstdlib>
@@ -490,6 +491,452 @@ namespace MEDCoupling
     std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+_nb_of_elem,_pointer.getPointer());
     return *this;
   }
+
+  //////////////////////////////////
+  
+  template<class T>
+  std::size_t DataArrayTemplate<T>::getHeapMemorySizeWithoutChildren() const
+  {
+    std::size_t sz(_mem.getNbOfElemAllocated());
+    sz*=sizeof(T);
+    return DataArray::getHeapMemorySizeWithoutChildren()+sz;
+  }
+  
+  /*!
+   * Allocates the raw data in memory. If the memory was already allocated, then it is
+   * freed and re-allocated. See an example of this method use
+   * \ref MEDCouplingArraySteps1WC "here".
+   *  \param [in] nbOfTuple - number of tuples of data to allocate.
+   *  \param [in] nbOfCompo - number of components of data to allocate.
+   *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::alloc(int nbOfTuple, int nbOfCompo)
+  {
+    if(nbOfTuple<0 || nbOfCompo<0)
+      {
+        std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::alloc : request for negative length of data !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+    _info_on_compo.resize(nbOfCompo);
+    _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
+    declareAsNew();
+  }
+
+  /*!
+   * Sets a C array to be used as raw data of \a this. The previously set info
+   *  of components is retained and re-sized. 
+   * For more info see \ref MEDCouplingArraySteps1.
+   *  \param [in] array - the C array to be used as raw data of \a this.
+   *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
+   *  \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
+   *                     \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
+   *                     \c free(\c array ) will be called.
+   *  \param [in] nbOfTuple - new number of tuples in \a this.
+   *  \param [in] nbOfCompo - new number of components in \a this.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::useArray(const T *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
+  {
+    _info_on_compo.resize(nbOfCompo);
+    _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
+    declareAsNew();
+  }
+  
+  template<class T>
+  void DataArrayTemplate<T>::useExternalArrayWithRWAccess(const T *array, int nbOfTuple, int nbOfCompo)
+  {
+    _info_on_compo.resize(nbOfCompo);
+    _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
+    declareAsNew();
+  }
+
+  /*!
+   * Returns a value located at specified tuple and component.
+   * This method is equivalent to DataArrayTemplate<T>::getIJ() except that validity of
+   * parameters is checked. So this method is safe but expensive if used to go through
+   * all values of \a this.
+   *  \param [in] tupleId - index of tuple of interest.
+   *  \param [in] compoId - index of component of interest.
+   *  \return double - value located by \a tupleId and \a compoId.
+   *  \throw If \a this is not allocated.
+   *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
+   *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
+   */
+  template<class T>
+  T DataArrayTemplate<T>::getIJSafe(int tupleId, int compoId) const
+  {
+    checkAllocated();
+    if(tupleId<0 || tupleId>=getNumberOfTuples())
+      {
+        std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+    if(compoId<0 || compoId>=getNumberOfComponents())
+      {
+        std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+    return _mem[tupleId*_info_on_compo.size()+compoId];
+  }
+
+  /*!
+   * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
+   *
+   * \sa DataArray::getHeapMemorySizeWithoutChildren, DataArrayTemplate<T>::reserve
+   */
+  template<class T>
+  void DataArrayTemplate<T>::pack() const
+  {
+    _mem.pack();
+  }
+
+  /*!
+   * Checks if raw data is allocated. Read more on the raw data
+   * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
+   *  \return bool - \a true if the raw data is allocated, \a false else.
+   */
+  template<class T>
+  bool DataArrayTemplate<T>::isAllocated() const
+  {
+    return getConstPointer()!=0;
+  }
+  
+  /*!
+   * Checks if raw data is allocated and throws an exception if it is not the case.
+   *  \throw If the raw data is not allocated.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::checkAllocated() const
+  {
+    if(!isAllocated())
+      {
+        std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+  }
+  
+  /*!
+   * This method desallocated \a this without modification of informations relative to the components.
+   * After call of this method, DataArrayDouble::isAllocated will return false.
+   * If \a this is already not allocated, \a this is let unchanged.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::desallocate()
+  {
+    _mem.destroy();
+  }
+
+  /*!
+   * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this.
+   * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
+   * If \a this has not already been allocated, number of components is set to one.
+   * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this.
+   * 
+   * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent
+   */
+  template<class T>
+  void DataArrayTemplate<T>::reserve(std::size_t nbOfElems)
+  {
+    int nbCompo(getNumberOfComponents());
+    if(nbCompo==1)
+      {
+        _mem.reserve(nbOfElems);
+      }
+    else if(nbCompo==0)
+      {
+        _mem.reserve(nbOfElems);
+        _info_on_compo.resize(1);
+      }
+    else
+      {
+        std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::reserve : not available for DataArrayDouble with number of components different than 1 !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+  }
+  
+  /*!
+   * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
+   * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
+   *
+   * \param [in] val the value to be added in \a this
+   * \throw If \a this has already been allocated with number of components different from one.
+   * \sa DataArrayDouble::pushBackValsSilent
+   */
+  template<class T>
+  void DataArrayTemplate<T>::pushBackSilent(T val)
+  {
+    int nbCompo(getNumberOfComponents());
+    if(nbCompo==1)
+      _mem.pushBack(val);
+    else if(nbCompo==0)
+      {
+        _info_on_compo.resize(1);
+        _mem.pushBack(val);
+      }
+    else
+      {
+        std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+  }
+  
+  /*!
+   * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
+   * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
+   *
+   *  \param [in] valsBg - an array of values to push at the end of \c this.
+   *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
+   *              the last value of \a valsBg is \a valsEnd[ -1 ].
+   * \throw If \a this has already been allocated with number of components different from one.
+   * \sa DataArrayDouble::pushBackSilent
+   */
+  template<class T>
+  void DataArrayTemplate<T>::pushBackValsSilent(const T *valsBg, const T *valsEnd)
+  {
+    int nbCompo(getNumberOfComponents());
+    if(nbCompo==1)
+      _mem.insertAtTheEnd(valsBg,valsEnd);
+    else if(nbCompo==0)
+      {
+        _info_on_compo.resize(1);
+        _mem.insertAtTheEnd(valsBg,valsEnd);
+      }
+    else
+      {
+        std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+  }
+  
+  /*!
+   * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
+   * \throw If \a this is already empty.
+   * \throw If \a this has number of components different from one.
+   */
+  template<class T>
+  T DataArrayTemplate<T>::popBackSilent()
+  {
+    if(getNumberOfComponents()==1)
+      return _mem.popBack();
+    else
+      {
+        std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::popBackSilent : not available for DataArrayDouble with number of components different than 1 !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+  }
+  
+  /*!
+   * Allocates the raw data in memory. If exactly same memory as needed already
+   * allocated, it is not re-allocated.
+   *  \param [in] nbOfTuple - number of tuples of data to allocate.
+   *  \param [in] nbOfCompo - number of components of data to allocate.
+   *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::allocIfNecessary(int nbOfTuple, int nbOfCompo)
+  {
+    if(isAllocated())
+      {
+        if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
+          alloc(nbOfTuple,nbOfCompo);
+      }
+    else
+      alloc(nbOfTuple,nbOfCompo);
+  }
+
+  /*!
+   * Checks the number of tuples.
+   *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
+   *  \throw If \a this is not allocated.
+   */
+  template<class T>
+  bool DataArrayTemplate<T>::empty() const
+  {
+    checkAllocated();
+    return getNumberOfTuples()==0;
+  }
+
+  /*!
+   * Copies all the data from another DataArrayDouble. For more info see
+   * \ref MEDCouplingArrayBasicsCopyDeepAssign.
+   *  \param [in] other - another instance of DataArrayDouble to copy data from.
+   *  \throw If the \a other is not allocated.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::deepCopyFrom(const DataArrayTemplate<T>& other)
+  {
+    other.checkAllocated();
+    int nbOfTuples(other.getNumberOfTuples()),nbOfComp(other.getNumberOfComponents());
+    allocIfNecessary(nbOfTuples,nbOfComp);
+    std::size_t nbOfElems((std::size_t)nbOfTuples*nbOfComp);
+    T *pt(getPointer());
+    const T *ptI(other.begin());
+    for(std::size_t i=0;i<nbOfElems;i++)
+      pt[i]=ptI[i];
+    copyStringInfoFrom(other);
+  }
+
+  /*!
+   * Reverse the array values.
+   *  \throw If \a this->getNumberOfComponents() < 1.
+   *  \throw If \a this is not allocated.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::reverse()
+  {
+    checkAllocated();
+    _mem.reverse(getNumberOfComponents());
+    declareAsNew();
+  }
+
+  /*!
+   * Assign \a val to all values in \a this array. To know more on filling arrays see
+   * \ref MEDCouplingArrayFill.
+   *  \param [in] val - the value to fill with.
+   *  \throw If \a this is not allocated.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::fillWithValue(T val)
+  {
+    checkAllocated();
+    _mem.fillWithValue(val);
+    declareAsNew();
+  }
+
+  /*!
+   * Changes number of tuples in the array. If the new number of tuples is smaller
+   * than the current number the array is truncated, otherwise the array is extended.
+   *  \param [in] nbOfTuples - new number of tuples. 
+   *  \throw If \a this is not allocated.
+   *  \throw If \a nbOfTuples is negative.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::reAlloc(int nbOfTuples)
+  {
+    if(nbOfTuples<0)
+      {
+        std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::reAlloc : input new number of tuples should be >=0 !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+    checkAllocated();
+    _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
+    declareAsNew();
+  }
+
+  /*!
+   * Permutes values of \a this array as required by \a old2New array. The values are
+   * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
+   * the same as in \c this one.
+   * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
+   * For more info on renumbering see \ref numbering.
+   *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
+   *     giving a new position for i-th old value.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::renumberInPlace(const int *old2New)
+  {
+    checkAllocated();
+    int nbTuples(getNumberOfTuples()),nbOfCompo(getNumberOfComponents());
+    T *tmp(new T[nbTuples*nbOfCompo]);
+    const T *iptr(begin());
+    for(int i=0;i<nbTuples;i++)
+      {
+        int v=old2New[i];
+        if(v>=0 && v<nbTuples)
+          std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
+        else
+          {
+            std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
+            throw INTERP_KERNEL::Exception(oss.str().c_str());
+          }
+      }
+    std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
+    delete [] tmp;
+    declareAsNew();
+  }
+
+
+  /*!
+   * Permutes values of \a this array as required by \a new2Old array. The values are
+   * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
+   * the same as in \c this one.
+   * For more info on renumbering see \ref numbering.
+   *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
+   *     giving a previous position of i-th new value.
+   *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
+   *          is to delete using decrRef() as it is no more needed.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::renumberInPlaceR(const int *new2Old)
+  {
+    checkAllocated();
+    int nbTuples(getNumberOfTuples()),nbOfCompo(getNumberOfComponents());
+    T *tmp(new T[nbTuples*nbOfCompo]);
+    const T *iptr(begin());
+    for(int i=0;i<nbTuples;i++)
+      {
+        int v=new2Old[i];
+        if(v>=0 && v<nbTuples)
+          std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
+        else
+          {
+            std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
+            throw INTERP_KERNEL::Exception(oss.str().c_str());
+          }
+      }
+    std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
+    delete [] tmp;
+    declareAsNew();
+  }
+
+  /*!
+   * Sorts values of the array.
+   *  \param [in] asc - \a true means ascending order, \a false, descending.
+   *  \throw If \a this is not allocated.
+   *  \throw If \a this->getNumberOfComponents() != 1.
+   */
+  template<class T>
+  void DataArrayTemplate<T>::sort(bool asc)
+  {
+    checkAllocated();
+    if(getNumberOfComponents()!=1)
+      {
+        std::ostringstream oss; oss << Traits<T>::ArrayTypeName << "::sort : only supported with 'this' array with ONE component !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+    _mem.sort(asc);
+    declareAsNew();
+  }
+
+  /*!
+   * Returns a copy of \a this array with values permuted as required by \a old2New array.
+   * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
+   * Number of tuples in the result array remains the same as in \c this one.
+   * If a permutation reduction is needed, renumberAndReduce() should be used.
+   * For more info on renumbering see \ref numbering.
+   *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
+   *          giving a new position for i-th old value.
+   *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
+   *          is to delete using decrRef() as it is no more needed.
+   *  \throw If \a this is not allocated.
+   */
+  template<class T>
+  typename Traits<T>::ArrayType *DataArrayTemplate<T>::renumber(const int *old2New) const
+  {
+    checkAllocated();
+    int nbTuples(getNumberOfTuples()),nbOfCompo(getNumberOfComponents());
+    MCAuto<DataArray> ret0(buildNewEmptyInstance());
+    MCAuto< typename Traits<T>::ArrayType > ret(DynamicCastSafe<DataArray,typename Traits<T>::ArrayType>(ret0));
+    ret->alloc(nbTuples,nbOfCompo);
+    ret->copyStringInfoFrom(*this);
+    const T *iptr(begin());
+    T *optr(ret->getPointer());
+    for(int i=0;i<nbTuples;i++)
+      std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
+    ret->copyStringInfoFrom(*this);
+    return ret.retn();
+  }
 }
 
 #endif
index 8a908b64cc1401aeb2c13b84945f29cbf0cc4f13..2557bc4421985d934cc0aa172e3461a383f7d5b3 100644 (file)
 
 using namespace MEDCoupling;
 
-/*!
- * Checks if raw data is allocated. Read more on the raw data
- * in \ref MEDCouplingArrayBasicsTuplesAndCompo "DataArrays infos" for more information.
- *  \return bool - \a true if the raw data is allocated, \a false else.
- */
-bool DataArrayChar::isAllocated() const
-{
-  return getConstPointer()!=0;
-}
-
-/*!
- * Checks if raw data is allocated and throws an exception if it is not the case.
- *  \throw If the raw data is not allocated.
- */
-void DataArrayChar::checkAllocated() const
-{
-  if(!isAllocated())
-    throw INTERP_KERNEL::Exception("DataArrayChar::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
-}
-
-/*!
- * This method desallocated \a this without modification of informations relative to the components.
- * After call of this method, DataArrayChar::isAllocated will return false.
- * If \a this is already not allocated, \a this is let unchanged.
- */
-void DataArrayChar::desallocate()
-{
-  _mem.destroy();
-}
-
-std::size_t DataArrayChar::getHeapMemorySizeWithoutChildren() const
-{
-  std::size_t sz(_mem.getNbOfElemAllocated());
-  return DataArray::getHeapMemorySizeWithoutChildren()+sz;
-}
+template class DataArrayTemplate<char>;
 
 /*!
  * Returns an integer value characterizing \a this array, which is useful for a quick
@@ -87,165 +53,6 @@ int DataArrayChar::getHashCode() const
   return ret+ret0;
 }
 
-/*!
- * Checks the number of tuples.
- *  \return bool - \a true if getNumberOfTuples() == 0, \a false else.
- *  \throw If \a this is not allocated.
- */
-bool DataArrayChar::empty() const
-{
-  checkAllocated();
-  return getNumberOfTuples()==0;
-}
-
-/*!
- * Copies all the data from another DataArrayChar. For more info see
- * \ref MEDCouplingArrayBasicsCopyDeepAssign.
- *  \param [in] other - another instance of DataArrayChar to copy data from.
- *  \throw If the \a other is not allocated.
- */
-void DataArrayChar::deepCopyFrom(const DataArrayChar& other)
-{
-  other.checkAllocated();
-  int nbOfTuples=other.getNumberOfTuples();
-  int nbOfComp=other.getNumberOfComponents();
-  allocIfNecessary(nbOfTuples,nbOfComp);
-  std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp;
-  char *pt=getPointer();
-  const char *ptI=other.getConstPointer();
-  for(std::size_t i=0;i<nbOfElems;i++)
-    pt[i]=ptI[i];
-  copyStringInfoFrom(other);
-}
-
-/*!
- * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this.
- * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown.
- * If \a this has not already been allocated, number of components is set to one.
- * This method allows to reduce number of reallocations on invokation of DataArrayChar::pushBackSilent and DataArrayChar::pushBackValsSilent on \a this.
- * 
- * \sa DataArrayChar::pack, DataArrayChar::pushBackSilent, DataArrayChar::pushBackValsSilent
- */
-void DataArrayChar::reserve(std::size_t nbOfElems)
-{
-  int nbCompo=getNumberOfComponents();
-  if(nbCompo==1)
-    {
-      _mem.reserve(nbOfElems);
-    }
-  else if(nbCompo==0)
-    {
-      _mem.reserve(nbOfElems);
-      _info_on_compo.resize(1);
-    }
-  else
-    throw INTERP_KERNEL::Exception("DataArrayChar::reserve : not available for DataArrayChar with number of components different than 1 !");
-}
-
-/*!
- * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation
- * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
- *
- * \param [in] val the value to be added in \a this
- * \throw If \a this has already been allocated with number of components different from one.
- * \sa DataArrayChar::pushBackValsSilent
- */
-void DataArrayChar::pushBackSilent(char val)
-{
-  int nbCompo=getNumberOfComponents();
-  if(nbCompo==1)
-    _mem.pushBack(val);
-  else if(nbCompo==0)
-    {
-      _info_on_compo.resize(1);
-      _mem.pushBack(val);
-    }
-  else
-    throw INTERP_KERNEL::Exception("DataArrayChar::pushBackSilent : not available for DataArrayChar with number of components different than 1 !");
-}
-
-/*!
- * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation
- * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session.
- *
- *  \param [in] valsBg - an array of values to push at the end of \this.
- *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
- *              the last value of \a valsBg is \a valsEnd[ -1 ].
- * \throw If \a this has already been allocated with number of components different from one.
- * \sa DataArrayChar::pushBackSilent
- */
-void DataArrayChar::pushBackValsSilent(const char *valsBg, const char *valsEnd)
-{
-  int nbCompo=getNumberOfComponents();
-  if(nbCompo==1)
-    _mem.insertAtTheEnd(valsBg,valsEnd);
-  else if(nbCompo==0)
-    {
-      _info_on_compo.resize(1);
-      _mem.insertAtTheEnd(valsBg,valsEnd);
-    }
-  else
-    throw INTERP_KERNEL::Exception("DataArrayChar::pushBackValsSilent : not available for DataArrayChar with number of components different than 1 !");
-}
-
-/*!
- * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it.
- * \throw If \a this is already empty.
- * \throw If \a this has number of components different from one.
- */
-char DataArrayChar::popBackSilent()
-{
-  if(getNumberOfComponents()==1)
-    return _mem.popBack();
-  else
-    throw INTERP_KERNEL::Exception("DataArrayChar::popBackSilent : not available for DataArrayChar with number of components different than 1 !");
-}
-
-/*!
- * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store.
- *
- * \sa DataArrayChar::getHeapMemorySizeWithoutChildren, DataArrayChar::reserve
- */
-void DataArrayChar::pack() const
-{
-  _mem.pack();
-}
-
-/*!
- * Allocates the raw data in memory. If exactly as same memory as needed already
- * allocated, it is not re-allocated.
- *  \param [in] nbOfTuple - number of tuples of data to allocate.
- *  \param [in] nbOfCompo - number of components of data to allocate.
- *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
- */
-void DataArrayChar::allocIfNecessary(int nbOfTuple, int nbOfCompo)
-{
-  if(isAllocated())
-    {
-      if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents())
-        alloc(nbOfTuple,nbOfCompo);
-    }
-  else
-    alloc(nbOfTuple,nbOfCompo);
-}
-
-/*!
- * Allocates the raw data in memory. If the memory was already allocated, then it is
- * freed and re-allocated. See an example of this method use
- * \ref MEDCouplingArraySteps1WC "here".
- *  \param [in] nbOfTuple - number of tuples of data to allocate.
- *  \param [in] nbOfCompo - number of components of data to allocate.
- *  \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0.
- */
-void DataArrayChar::alloc(int nbOfTuple, int nbOfCompo)
-{
-  if(nbOfTuple<0 || nbOfCompo<0)
-    throw INTERP_KERNEL::Exception("DataArrayChar::alloc : request for negative length of data !");
-  _info_on_compo.resize(nbOfCompo);
-  _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple);
-  declareAsNew();
-}
-
 /*!
  * Checks if \a this and another DataArrayChar are fully equal. For more info see
  * \ref MEDCouplingArrayBasicsCompare.
@@ -285,18 +92,6 @@ bool DataArrayChar::isEqualWithoutConsideringStr(const DataArrayChar& other) con
   return _mem.isEqual(other._mem,0,tmp);
 }
 
-/*!
- * Reverse the array values.
- *  \throw If \a this->getNumberOfComponents() < 1.
- *  \throw If \a this is not allocated.
- */
-void DataArrayChar::reverse()
-{
-  checkAllocated();
-  _mem.reverse(getNumberOfComponents());
-  declareAsNew();
-}
-
 /*!
  * Assign zero to all values in \a this array. To know more on filling arrays see
  * \ref MEDCouplingArrayFill.
@@ -304,22 +99,7 @@ void DataArrayChar::reverse()
  */
 void DataArrayChar::fillWithZero()
 {
-  checkAllocated();
-  _mem.fillWithValue(0);
-  declareAsNew();
-}
-
-/*!
- * Assign \a val to all values in \a this array. To know more on filling arrays see
- * \ref MEDCouplingArrayFill.
- *  \param [in] val - the value to fill with.
- *  \throw If \a this is not allocated.
- */
-void DataArrayChar::fillWithValue(char val)
-{
-  checkAllocated();
-  _mem.fillWithValue(val);
-  declareAsNew();
+  fillWithValue(0);
 }
 
 /*!
@@ -341,22 +121,6 @@ std::string DataArrayChar::reprZip() const
   return ret.str();
 }
 
-/*!
- * Changes number of tuples in the array. If the new number of tuples is smaller
- * than the current number the array is truncated, otherwise the array is extended.
- *  \param [in] nbOfTuples - new number of tuples. 
- *  \throw If \a this is not allocated.
- *  \throw If \a nbOfTuples is negative.
- */
-void DataArrayChar::reAlloc(int nbOfTuples)
-{
-  if(nbOfTuples<0)
-    throw INTERP_KERNEL::Exception("DataArrayChar::reAlloc : input new number of tuples should be >=0 !");
-  checkAllocated();
-  _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
-  declareAsNew();
-}
-
 /*!
  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
  * array to the new one.
@@ -375,79 +139,6 @@ DataArrayInt *DataArrayChar::convertToIntArr() const
   return ret;
 }
 
-/*!
- * Permutes values of \a this array as required by \a old2New array. The values are
- * permuted so that \c new[ \a old2New[ i ]] = \c old[ i ]. Number of tuples remains
- * the same as in \this one.
- * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
- * For more info on renumbering see \ref numbering.
- *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
- *     giving a new position for i-th old value.
- */
-void DataArrayChar::renumberInPlace(const int *old2New)
-{
-  checkAllocated();
-  int nbTuples=getNumberOfTuples();
-  int nbOfCompo=getNumberOfComponents();
-  char *tmp=new char[nbTuples*nbOfCompo];
-  const char *iptr=getConstPointer();
-  for(int i=0;i<nbTuples;i++)
-    std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
-  std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
-  delete [] tmp;
-  declareAsNew();
-}
-
-/*!
- * Permutes values of \a this array as required by \a new2Old array. The values are
- * permuted so that \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of tuples remains
- * the same as in \this one.
- * For more info on renumbering see \ref numbering.
- *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
- *     giving a previous position of i-th new value.
- */
-void DataArrayChar::renumberInPlaceR(const int *new2Old)
-{
-  checkAllocated();
-  int nbTuples=getNumberOfTuples();
-  int nbOfCompo=getNumberOfComponents();
-  char *tmp=new char[nbTuples*nbOfCompo];
-  const char *iptr=getConstPointer();
-  for(int i=0;i<nbTuples;i++)
-    std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
-  std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
-  delete [] tmp;
-  declareAsNew();
-}
-
-/*!
- * Returns a copy of \a this array with values permuted as required by \a old2New array.
- * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ].
- * Number of tuples in the result array remains the same as in \this one.
- * If a permutation reduction is needed, renumberAndReduce() should be used.
- * For more info on renumbering see \ref numbering.
- *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
- *          giving a new position for i-th old value.
- *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
- *          is to delete using decrRef() as it is no more needed.
- *  \throw If \a this is not allocated.
- */
-DataArrayChar *DataArrayChar::renumber(const int *old2New) const
-{
-  checkAllocated();
-  int nbTuples=getNumberOfTuples();
-  int nbOfCompo=getNumberOfComponents();
-  MCAuto<DataArrayChar> ret=buildEmptySpecializedDAChar();
-  ret->alloc(nbTuples,nbOfCompo);
-  ret->copyStringInfoFrom(*this);
-  const char *iptr=getConstPointer();
-  char *optr=ret->getPointer();
-  for(int i=0;i<nbTuples;i++)
-    std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]);
-  ret->copyStringInfoFrom(*this);
-  return ret.retn();
-}
-
 /*!
  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
@@ -1478,34 +1169,6 @@ DataArray *DataArrayChar::selectByTupleRanges(const std::vector<std::pair<int,in
   return ret.retn();
 }
 
-/*!
- * Returns a value located at specified tuple and component.
- * This method is equivalent to DataArrayChar::getIJ() except that validity of
- * parameters is checked. So this method is safe but expensive if used to go through
- * all values of \a this.
- *  \param [in] tupleId - index of tuple of interest.
- *  \param [in] compoId - index of component of interest.
- *  \return char - value located by \a tupleId and \a compoId.
- *  \throw If \a this is not allocated.
- *  \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated.
- *  \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated.
- */
-char DataArrayChar::getIJSafe(int tupleId, int compoId) const
-{
-  checkAllocated();
-  if(tupleId<0 || tupleId>=getNumberOfTuples())
-    {
-      std::ostringstream oss; oss << "DataArrayChar::getIJSafe : request for tupleId " << tupleId << " should be in [0," << getNumberOfTuples() << ") !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  if(compoId<0 || compoId>=getNumberOfComponents())
-    {
-      std::ostringstream oss; oss << "DataArrayChar::getIJSafe : request for compoId " << compoId << " should be in [0," << getNumberOfComponents() << ") !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  return _mem[tupleId*_info_on_compo.size()+compoId];
-}
-
 /*!
  * Returns the first value of \a this. 
  *  \return char - the last value of \a this array.
@@ -1957,32 +1620,6 @@ DataArrayChar *DataArrayChar::Meld(const std::vector<const DataArrayChar *>& arr
   return ret;
 }
 
-/*!
- * Sets a C array to be used as raw data of \a this. The previously set info
- *  of components is retained and re-sized. 
- * For more info see \ref MEDCouplingArraySteps1.
- *  \param [in] array - the C array to be used as raw data of \a this.
- *  \param [in] ownership - if \a true, \a array will be deallocated at destruction of \a this.
- *  \param [in] type - specifies how to deallocate \a array. If \a type == MEDCoupling::CPP_DEALLOC,
- *                     \c delete [] \c array; will be called. If \a type == MEDCoupling::C_DEALLOC,
- *                     \c free(\c array ) will be called.
- *  \param [in] nbOfTuple - new number of tuples in \a this.
- *  \param [in] nbOfCompo - new number of components in \a this.
- */
-void DataArrayChar::useArray(const char *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
-{
-  _info_on_compo.resize(nbOfCompo);
-  _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo);
-  declareAsNew();
-}
-
-void DataArrayChar::useExternalArrayWithRWAccess(const char *array, int nbOfTuple, int nbOfCompo)
-{
-  _info_on_compo.resize(nbOfCompo);
-  _mem.useExternalArrayWithRWAccess(array,(std::size_t)nbOfTuple*nbOfCompo);
-  declareAsNew();
-}
-
 /*!
  * Returns a new instance of DataArrayByte. The caller is to delete this array
  * using decrRef() as it is no more needed. 
diff --git a/src/MEDCoupling/MEDCouplingTraits.cxx b/src/MEDCoupling/MEDCouplingTraits.cxx
new file mode 100644 (file)
index 0000000..a764675
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (C) 2016  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, 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
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#include "MEDCouplingTraits.hxx"
+
+using namespace MEDCoupling;
+
+const char Traits<double>::ArrayTypeName[]="DataArrayDouble";
+
+const char Traits<int>::ArrayTypeName[]="DataArrayInt";
+
+const char Traits<char>::ArrayTypeName[]="DataArrayChar";
diff --git a/src/MEDCoupling/MEDCouplingTraits.hxx b/src/MEDCoupling/MEDCouplingTraits.hxx
new file mode 100644 (file)
index 0000000..c4b7ed7
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (C) 2016  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, 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
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony Geay (EDF R&D)
+
+#ifndef __MEDCOUPLINGTRAITS_HXX__
+#define __MEDCOUPLINGTRAITS_HXX__
+
+namespace MEDCoupling
+{
+  template<class T>
+  struct Traits
+  {
+    typedef T EltType;
+  };
+
+  class DataArrayInt;
+  class DataArrayDouble;
+  class DataArrayChar;
+  
+  template<>
+  struct Traits<double>
+  {
+    static const char ArrayTypeName[];
+    typedef DataArrayDouble ArrayType;
+  };
+  
+  template<>
+  struct Traits<int>
+  {
+    static const char ArrayTypeName[];
+    typedef DataArrayInt ArrayType;
+  };
+
+  template<>
+  struct Traits<char>
+  {
+    static const char ArrayTypeName[];
+    typedef DataArrayChar ArrayType;
+  };
+}
+
+#endif
index 7beeb58a45a6483136e5a15f52fa88a2b8698809..d30ed5bb6ea67008a908c59a27e6aa549c92b18e 100644 (file)
@@ -43,6 +43,7 @@
 //$$$$$$$$$$$$$$$$$$
 
 %newobject MEDCoupling::DataArray::deepCopy;
+%newobject MEDCoupling::DataArray::buildNewEmptyInstance;
 %newobject MEDCoupling::DataArray::selectByTupleRanges;
 %newobject MEDCoupling::DataArray::selectByTupleId;
 %newobject MEDCoupling::DataArray::selectByTupleIdSafe;
@@ -240,6 +241,7 @@ namespace MEDCoupling
     virtual std::size_t getNbOfElems() const throw(INTERP_KERNEL::Exception);
     virtual std::size_t getNbOfElemAllocated() const throw(INTERP_KERNEL::Exception);
     virtual DataArray *deepCopy() const throw(INTERP_KERNEL::Exception);
+    virtual DataArray *buildNewEmptyInstance() const throw(INTERP_KERNEL::Exception);
     virtual DataArray *selectByTupleIdSafeSlice(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception);
     virtual void rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception);
     void checkNbOfTuples(int nbOfTuples, const std::string& msg) const throw(INTERP_KERNEL::Exception);
@@ -4970,6 +4972,7 @@ namespace MEDCoupling
     DataArrayChar *renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception);
     DataArrayChar *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const throw(INTERP_KERNEL::Exception);
     bool isUniform(char val) const throw(INTERP_KERNEL::Exception);
+    void sort(bool asc=true) throw(INTERP_KERNEL::Exception);
     DataArrayChar *subArray(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception);
     DataArrayChar *changeNbOfComponents(int newNbOfComp, char dftValue) const throw(INTERP_KERNEL::Exception);
     void meldWith(const DataArrayChar *other) throw(INTERP_KERNEL::Exception);