Salome HOME
Merge remote branch 'origin/V7_4_BR'
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
index ff071afa6900e094d3a01acf462312d08df7ede6..d6d65c9e8bc3010ac364484c5b861246b69a7fe7 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2013  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -120,7 +120,7 @@ std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
   return sz1+sz2+sz3;
 }
 
-std::vector<const BigMemoryObject *> DataArray::getDirectChildren() const
+std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
 {
   return std::vector<const BigMemoryObject *>();
 }
@@ -130,7 +130,7 @@ std::vector<const BigMemoryObject *> DataArray::getDirectChildren() const
  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
  *  \param [in] name - new array name
  */
-void DataArray::setName(const char *name)
+void DataArray::setName(const std::string& name)
 {
   _name=name;
 }
@@ -164,7 +164,7 @@ void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vect
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   for(std::size_t i=0;i<newNbOfCompo;i++)
-    setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]).c_str());
+    setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
 }
 
 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
@@ -180,7 +180,7 @@ void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, cons
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   for(std::size_t i=0;i<partOfCompoToSet;i++)
-    setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i).c_str());
+    setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
 }
 
 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
@@ -231,7 +231,7 @@ void DataArray::reprWithoutNameStream(std::ostream& stream) const
   stream << "\n";
 }
 
-std::string DataArray::cppRepr(const char *varName) const
+std::string DataArray::cppRepr(const std::string& varName) const
 {
   std::ostringstream ret;
   reprCppStream(varName,ret);
@@ -422,6 +422,18 @@ std::string DataArray::GetUnitFromInfo(const std::string& info)
   return info.substr(p1+1,p2-p1-1);
 }
 
+/*!
+ * This method put in info format the result of the merge of \a var and \a unit.
+ * The standard format for that is "var [unit]".
+ * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
+ */
+std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
+{
+  std::ostringstream oss;
+  oss << var << " [" << unit << "]";
+  return oss.str();
+}
+
 /*!
  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
@@ -478,7 +490,7 @@ DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
  *  \param [in] info - the string containing the information.
  *  \throw If \a i is not a valid component index.
  */
-void DataArray::setInfoOnComponent(int i, const char *info)
+void DataArray::setInfoOnComponent(int i, const std::string& info)
 {
   if(i<(int)_info_on_compo.size() && i>=0)
     _info_on_compo[i]=info;
@@ -516,7 +528,7 @@ void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
     _info_on_compo=info;
 }
 
-void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const
+void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
 {
   if(getNumberOfTuples()!=nbOfTuples)
     {
@@ -525,7 +537,7 @@ void DataArray::checkNbOfTuples(int nbOfTuples, const char *msg) const
     }
 }
 
-void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const
+void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
 {
   if(getNumberOfComponents()!=nbOfCompo)
     {
@@ -534,7 +546,7 @@ void DataArray::checkNbOfComps(int nbOfCompo, const char *msg) const
     }
 }
 
-void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const
+void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
 {
   if(getNbOfElems()!=nbOfElems)
     {
@@ -543,9 +555,9 @@ void DataArray::checkNbOfElems(std::size_t nbOfElems, const char *msg) const
     }
 }
 
-void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const
+void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
 {
-   if(getNumberOfTuples()!=other.getNumberOfTuples())
+  if(getNumberOfTuples()!=other.getNumberOfTuples())
     {
       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
@@ -557,7 +569,7 @@ void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const char *msg)
     }
 }
 
-void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const
+void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
 {
   checkNbOfTuples(nbOfTuples,msg);
   checkNbOfComps(nbOfCompo,msg);
@@ -566,7 +578,7 @@ void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char
 /*!
  * Simply this method checks that \b value is in [0,\b ref).
  */
-void DataArray::CheckValueInRange(int ref, int value, const char *msg)
+void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
 {
   if(value<0 || value>=ref)
     {
@@ -579,7 +591,7 @@ void DataArray::CheckValueInRange(int ref, int value, const char *msg)
  * This method checks that [\b start, \b end) is compliant with ref length \b value.
  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
  */
-void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *msg)
+void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
 {
   if(start<0 || start>=value)
     {
@@ -596,7 +608,7 @@ void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *m
     }
 }
 
-void DataArray::CheckClosingParInRange(int ref, int value, const char *msg)
+void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
 {
   if(value<0 || value>ref)
     {
@@ -644,7 +656,7 @@ void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSli
     stopSlice=stop;
 }
 
-int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg)
+int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
 {
   if(end<begin)
     {
@@ -661,7 +673,7 @@ int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char
   return (end-1-begin)/step+1;
 }
 
-int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const char *msg)
+int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
 {
   if(step==0)
     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
@@ -1150,7 +1162,7 @@ std::string DataArrayDouble::reprZip() const
   return ret.str();
 }
 
-void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile, DataArrayByte *byteArr) const
+void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
 {
   static const char SPACE[4]={' ',' ',' ',' '};
   checkAllocated();
@@ -1204,7 +1216,7 @@ void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
   _mem.reprZip(getNumberOfComponents(),stream);
 }
 
-void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const
+void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
 {
   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
   const double *data=getConstPointer();
@@ -1783,10 +1795,10 @@ DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double d
       for(;j<newNbOfComp;j++)
         nc[newNbOfComp*i+j]=dftValue;
     }
-  ret->setName(getName().c_str());
+  ret->setName(getName());
   for(int i=0;i<dim;i++)
-    ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
-  ret->setName(getName().c_str());
+    ret->setInfoOnComponent(i,getInfoOnComponent(i));
+  ret->setName(getName());
   return ret.retn();
 }
 
@@ -1846,9 +1858,11 @@ void DataArrayDouble::transpose()
  *  \throw If a component index (\a i) is not valid: 
  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example".
+ *  \endif
  */
-DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
+DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const
 {
   checkAllocated();
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New());
@@ -1879,9 +1893,11 @@ DataArray *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compo
  *  \throw If \a this is not allocated.
  *  \throw If \a this and \a other arrays have different number of tuples.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
  *
  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
+ *  \endif
  */
 void DataArrayDouble::meldWith(const DataArrayDouble *other)
 {
@@ -1961,9 +1977,11 @@ bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec,
  *  \throw If \a this is not allocated.
  *  \throw If the number of components is not in [1,2,3,4].
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
  *
  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
+ *  \endif
  *  \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
  */
 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
@@ -1972,12 +1990,12 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI
   int nbOfCompo=getNumberOfComponents();
   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
-  
+
   int nbOfTuples=getNumberOfTuples();
   //
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
   switch(nbOfCompo)
-    {
+  {
     case 4:
       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
       break;
@@ -1992,7 +2010,7 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI
       break;
     default:
       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
-    }
+  }
   comm=c.retn();
   commIndex=cI.retn();
 }
@@ -2080,7 +2098,7 @@ DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other)
   double bounds[6];
   getMinMaxPerComponent(bounds);
   switch(nbOfCompo)
-    {
+  {
     case 3:
       {
         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
@@ -2108,7 +2126,7 @@ DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other)
       }
     default:
       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
-    }
+  }
   return ret.retn();
 }
 
@@ -2145,7 +2163,7 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble
   const double *thisBBPtr(begin());
   int *retPtr(ret->getPointer());
   switch(nbOfComp/2)
-    {
+  {
     case 3:
       {
         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
@@ -2169,8 +2187,8 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble
       }
     default:
       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
-    }
-  
+  }
+
   return ret.retn();
 }
 
@@ -2190,7 +2208,9 @@ DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble
  *  \throw If \a this is not allocated.
  *  \throw If the number of components is not in [1,2,3,4].
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
+ *  \endif
  */
 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
 {
@@ -2214,7 +2234,9 @@ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTuple
  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
+ *  \endif
  */
 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
 {
@@ -2264,7 +2286,9 @@ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std:
  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example".
+ *  \endif
  */
 void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
 {
@@ -2327,7 +2351,9 @@ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, i
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example".
+ *  \endif
  */
 void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
 {
@@ -2381,7 +2407,9 @@ void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTupl
  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example".
+ *  \endif
  */
 void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
 {
@@ -2452,7 +2480,9 @@ void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTu
  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
  *         out of a valid range for \a this array.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example".
+ *  \endif
  */
 void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
 {
@@ -2512,7 +2542,9 @@ void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, cons
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example".
+ *  \endif
  */
 void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
 {
@@ -2584,7 +2616,9 @@ void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTu
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example".
+ *  \endif
  */
 void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
 {
@@ -3084,7 +3118,7 @@ void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, do
   int nbOfTuplesOther=other->getNumberOfTuples();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
   switch(nbOfCompo)
-    {
+  {
     case 3:
       {
         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
@@ -3105,7 +3139,7 @@ void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, do
       }
     default:
       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
-    }
+  }
   c=cArr.retn(); cI=cIArr.retn();
 }
 
@@ -3536,7 +3570,7 @@ DataArrayDouble *DataArrayDouble::fromCylToCart() const
       w[1]=wIn[0]*sin(wIn[1]);
       w[2]=wIn[2];
     }
-  ret->setInfoOnComponent(2,getInfoOnComponent(2).c_str());
+  ret->setInfoOnComponent(2,getInfoOnComponent(2));
   return ret;
 }
 
@@ -3615,7 +3649,7 @@ DataArrayDouble *DataArrayDouble::determinant() const
   const double *src=getConstPointer();
   double *dest=ret->getPointer();
   switch(getNumberOfComponents())
-    {
+  {
     case 6:
       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
         *dest=src[0]*src[1]*src[2]+2.*src[4]*src[5]*src[3]-src[0]*src[4]*src[4]-src[2]*src[3]*src[3]-src[1]*src[5]*src[5];
@@ -3631,7 +3665,7 @@ DataArrayDouble *DataArrayDouble::determinant() const
     default:
       ret->decrRef();
       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
-    }
+  }
 }
 
 /*!
@@ -3713,7 +3747,7 @@ DataArrayDouble *DataArrayDouble::inverse() const
   ret->alloc(nbOfTuple,nbOfComp);
   const double *src=getConstPointer();
   double *dest=ret->getPointer();
-if(nbOfComp==6)
+  if(nbOfComp==6)
     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
       {
         double det=src[0]*src[1]*src[2]+2.*src[4]*src[5]*src[3]-src[0]*src[4]*src[4]-src[2]*src[3]*src[3]-src[1]*src[5]*src[5];
@@ -4074,26 +4108,30 @@ DataArrayDouble *DataArrayDouble::computeAbs() const
 }
 
 /*!
- * Apply a liner function to a given component of \a this array, so that
+ * Apply a linear function to a given component of \a this array, so that
  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
  *  \param [in] a - the first coefficient of the function.
  *  \param [in] b - the second coefficient of the function.
  *  \param [in] compoId - the index of component to modify.
- *  \throw If \a this is not allocated.
+ *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
  */
 void DataArrayDouble::applyLin(double a, double b, int compoId)
 {
   checkAllocated();
-  double *ptr=getPointer()+compoId;
-  int nbOfComp=getNumberOfComponents();
-  int nbOfTuple=getNumberOfTuples();
+  double *ptr(getPointer()+compoId);
+  int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
+  if(compoId<0 || compoId>=nbOfComp)
+    {
+      std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
     *ptr=a*(*ptr)+b;
   declareAsNew();
 }
 
 /*!
- * Apply a liner function to all elements of \a this array, so that
+ * Apply a linear function to all elements of \a this array, so that
  * an element _x_ becomes \f$ a * x + b \f$.
  *  \param [in] a - the first coefficient of the function.
  *  \param [in] b - the second coefficient of the function.
@@ -4269,6 +4307,8 @@ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate fun
  *  \param [in] nbOfComp - number of components in the result array.
  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
+ *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
+ *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
  *          same number of tuples as \a this array and \a nbOfComp components.
  *          The caller is to delete this result array using decrRef() as it is no more
@@ -4276,144 +4316,210 @@ DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate fun
  *  \throw If \a this is not allocated.
  *  \throw If computing \a func fails.
  */
-DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const
+DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
 {
-  checkAllocated();
   INTERP_KERNEL::ExprParser expr(func);
   expr.parse();
   std::set<std::string> vars;
   expr.getTrueSetOfVars(vars);
-  int oldNbOfComp=getNumberOfComponents();
-  if((int)vars.size()>oldNbOfComp)
-    {
-      std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
-      oss << vars.size() << " variables : ";
-      std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
   std::vector<std::string> varsV(vars.begin(),vars.end());
-  expr.prepareExprEvaluation(varsV,oldNbOfComp,nbOfComp);
-  //
-  DataArrayDouble *newArr=DataArrayDouble::New();
-  int nbOfTuples=getNumberOfTuples();
-  newArr->alloc(nbOfTuples,nbOfComp);
-  const double *ptr=getConstPointer();
-  double *ptrToFill=newArr->getPointer();
-  for(int i=0;i<nbOfTuples;i++)
-    {
-      try
-        {
-          expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
-        }
-      catch(INTERP_KERNEL::Exception& e)
-        {
-          std::ostringstream oss; oss << "For tuple # " << i << " with value (";
-          std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
-          oss << ") : Evaluation of function failed !" << e.what();
-          newArr->decrRef();
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  return newArr;
+  return applyFunc3(nbOfComp,varsV,func,isSafe);
 }
 
 /*!
  * Returns a new DataArrayDouble created from \a this one by applying a function to every
- * tuple of \a this array. Textual data is not copied.
+ * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
+ * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
+ *
  * For more info see \ref MEDCouplingArrayApplyFunc0.
  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
+ *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
+ *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
  *          same number of tuples and components as \a this array.
  *          The caller is to delete this result array using decrRef() as it is no more
  *          needed.
+ *  \sa applyFuncOnThis
  *  \throw If \a this is not allocated.
  *  \throw If computing \a func fails.
  */
-DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const
+DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
 {
+  int nbOfComp(getNumberOfComponents());
+  if(nbOfComp<=0)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
   checkAllocated();
+  int nbOfTuples(getNumberOfTuples());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
+  newArr->alloc(nbOfTuples,nbOfComp);
   INTERP_KERNEL::ExprParser expr(func);
   expr.parse();
-  expr.prepareExprEvaluationVec();
-  //
-  DataArrayDouble *newArr=DataArrayDouble::New();
-  int nbOfTuples=getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  newArr->alloc(nbOfTuples,nbOfComp);
-  const double *ptr=getConstPointer();
-  double *ptrToFill=newArr->getPointer();
-  for(int i=0;i<nbOfTuples;i++)
+  std::set<std::string> vars;
+  expr.getTrueSetOfVars(vars);
+  if((int)vars.size()>1)
+    {
+      std::ostringstream oss; oss << "DataArrayDouble::applyFunc : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFunc2 or applyFunc3 instead ! Vars in expr are : ";
+      std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  if(vars.empty())
+    {
+      expr.prepareFastEvaluator();
+      newArr->rearrange(1);
+      newArr->fillWithValue(expr.evaluateDouble());
+      newArr->rearrange(nbOfComp);
+      return newArr.retn();
+    }
+  std::vector<std::string> vars2(vars.begin(),vars.end());
+  double buff,*ptrToFill(newArr->getPointer());
+  const double *ptr(begin());
+  std::vector<double> stck;
+  expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
+  expr.prepareFastEvaluator();
+  if(!isSafe)
     {
-      try
+      for(int i=0;i<nbOfTuples;i++)
         {
-          expr.evaluateExpr(nbOfComp,ptr+i*nbOfComp,ptrToFill+i*nbOfComp);
+          for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
+            {
+              buff=*ptr;
+              expr.evaluateDoubleInternal(stck);
+              *ptrToFill=stck.back();
+              stck.pop_back();
+            }
         }
-      catch(INTERP_KERNEL::Exception& e)
+    }
+  else
+    {
+      for(int i=0;i<nbOfTuples;i++)
         {
-          std::ostringstream oss; oss << "For tuple # " << i << " with value (";
-          std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
-          oss << ") : Evaluation of function failed ! " << e.what();
-          newArr->decrRef();
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
+          for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
+            {
+              buff=*ptr;
+              try
+              {
+                  expr.evaluateDoubleInternalSafe(stck);
+              }
+              catch(INTERP_KERNEL::Exception& e)
+              {
+                  std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
+                  oss << buff;
+                  oss << ") : Evaluation of function failed !" << e.what();
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+              }
+              *ptrToFill=stck.back();
+              stck.pop_back();
+            }
         }
     }
-  return newArr;
+  return newArr.retn();
 }
 
 /*!
- * Returns a new DataArrayDouble created from \a this one by applying a function to every
- * tuple of \a this array. Textual data is not copied.
- * For more info see \ref MEDCouplingArrayApplyFunc2.
- *  \param [in] nbOfComp - number of components in the result array.
+ * This method is a non const method that modify the array in \a this.
+ * This method only works on one component array. It means that function \a func must
+ * contain at most one variable.
+ * This method is a specialization of applyFunc method with one parameter on one component array.
+ *
  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
- *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
- *          same number of tuples as \a this array.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If \a this is not allocated.
- *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
- *  \throw If computing \a func fails.
+ *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
+ *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
+ *
+ * \sa applyFunc
  */
-DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) const
+void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
 {
+  int nbOfComp(getNumberOfComponents());
+  if(nbOfComp<=0)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
   checkAllocated();
+  int nbOfTuples(getNumberOfTuples());
   INTERP_KERNEL::ExprParser expr(func);
   expr.parse();
   std::set<std::string> vars;
   expr.getTrueSetOfVars(vars);
-  int oldNbOfComp=getNumberOfComponents();
-  if((int)vars.size()>oldNbOfComp)
+  if((int)vars.size()>1)
     {
-      std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
-      oss << vars.size() << " variables : ";
+      std::ostringstream oss; oss << "DataArrayDouble::applyFuncOnThis : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFunc2 or applyFunc3 instead ! Vars in expr are : ";
       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  expr.prepareExprEvaluation(getVarsOnComponent(),oldNbOfComp,nbOfComp);
-  //
-  DataArrayDouble *newArr=DataArrayDouble::New();
-  int nbOfTuples=getNumberOfTuples();
-  newArr->alloc(nbOfTuples,nbOfComp);
-  const double *ptr=getConstPointer();
-  double *ptrToFill=newArr->getPointer();
-  for(int i=0;i<nbOfTuples;i++)
+  if(vars.empty())
+    {
+      expr.prepareFastEvaluator();
+      std::vector<std::string> compInfo(getInfoOnComponents());
+      rearrange(1);
+      fillWithValue(expr.evaluateDouble());
+      rearrange(nbOfComp);
+      setInfoOnComponents(compInfo);
+      return ;
+    }
+  std::vector<std::string> vars2(vars.begin(),vars.end());
+  double buff,*ptrToFill(getPointer());
+  const double *ptr(begin());
+  std::vector<double> stck;
+  expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
+  expr.prepareFastEvaluator();
+  if(!isSafe)
     {
-      try
+      for(int i=0;i<nbOfTuples;i++)
         {
-          expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
+          for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
+            {
+              buff=*ptr;
+              expr.evaluateDoubleInternal(stck);
+              *ptrToFill=stck.back();
+              stck.pop_back();
+            }
         }
-      catch(INTERP_KERNEL::Exception& e)
+    }
+  else
+    {
+      for(int i=0;i<nbOfTuples;i++)
         {
-          std::ostringstream oss; oss << "For tuple # " << i << " with value (";
-          std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
-          oss << ") : Evaluation of function failed !" << e.what();
-          newArr->decrRef();
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
+          for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
+            {
+              buff=*ptr;
+              try
+              {
+                  expr.evaluateDoubleInternalSafe(stck);
+              }
+              catch(INTERP_KERNEL::Exception& e)
+              {
+                  std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
+                  oss << buff;
+                  oss << ") : Evaluation of function failed !" << e.what();
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+              }
+              *ptrToFill=stck.back();
+              stck.pop_back();
+            }
         }
     }
-  return newArr;
+}
+
+/*!
+ * Returns a new DataArrayDouble created from \a this one by applying a function to every
+ * tuple of \a this array. Textual data is not copied.
+ * For more info see \ref MEDCouplingArrayApplyFunc2.
+ *  \param [in] nbOfComp - number of components in the result array.
+ *  \param [in] func - the expression defining how to transform a tuple of \a this array.
+ *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
+ *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
+ *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
+ *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
+ *          same number of tuples as \a this array.
+ *          The caller is to delete this result array using decrRef() as it is no more
+ *          needed.
+ *  \throw If \a this is not allocated.
+ *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
+ *  \throw If computing \a func fails.
+ */
+DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const std::string& func, bool isSafe) const
+{
+  return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe);
 }
 
 /*!
@@ -4424,6 +4530,8 @@ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) con
  *  \param [in] varsOrder - sequence of vars defining their order.
  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
+ *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
+ *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
  *          same number of tuples as \a this array.
  *          The caller is to delete this result array using decrRef() as it is no more
@@ -4432,14 +4540,20 @@ DataArrayDouble *DataArrayDouble::applyFunc2(int nbOfComp, const char *func) con
  *  \throw If \a func contains vars not in \a varsOrder.
  *  \throw If computing \a func fails.
  */
-DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
+DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
 {
+  if(nbOfComp<=0)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : output number of component must be > 0 !");
+  std::vector<std::string> varsOrder2(varsOrder);
+  int oldNbOfComp(getNumberOfComponents());
+  for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
+    varsOrder2.push_back(std::string());
   checkAllocated();
+  int nbOfTuples(getNumberOfTuples());
   INTERP_KERNEL::ExprParser expr(func);
   expr.parse();
   std::set<std::string> vars;
   expr.getTrueSetOfVars(vars);
-  int oldNbOfComp=getNumberOfComponents();
   if((int)vars.size()>oldNbOfComp)
     {
       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
@@ -4447,32 +4561,52 @@ DataArrayDouble *DataArrayDouble::applyFunc3(int nbOfComp, const std::vector<std
       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  expr.prepareExprEvaluation(varsOrder,oldNbOfComp,nbOfComp);
-  //
-  DataArrayDouble *newArr=DataArrayDouble::New();
-  int nbOfTuples=getNumberOfTuples();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New());
   newArr->alloc(nbOfTuples,nbOfComp);
-  const double *ptr=getConstPointer();
-  double *ptrToFill=newArr->getPointer();
-  for(int i=0;i<nbOfTuples;i++)
-    {
-      try
-        {
-          expr.evaluateExpr(nbOfComp,ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp);
+  INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
+  double *buffPtr(buff),*ptrToFill;
+  std::vector<double> stck;
+  for(int iComp=0;iComp<nbOfComp;iComp++)
+    {
+      expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
+      expr.prepareFastEvaluator();
+      const double *ptr(getConstPointer());
+      ptrToFill=newArr->getPointer()+iComp;
+      if(!isSafe)
+        {
+          for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
+            {
+              std::copy(ptr,ptr+oldNbOfComp,buffPtr);
+              expr.evaluateDoubleInternal(stck);
+              *ptrToFill=stck.back();
+              stck.pop_back();
+            }
         }
-      catch(INTERP_KERNEL::Exception& e)
+      else
         {
-          std::ostringstream oss; oss << "For tuple # " << i << " with value (";
-          std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
-          oss << ") : Evaluation of function failed !" << e.what();
-          newArr->decrRef();
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
+          for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
+            {
+              std::copy(ptr,ptr+oldNbOfComp,buffPtr);
+              try
+              {
+                  expr.evaluateDoubleInternalSafe(stck);
+                  *ptrToFill=stck.back();
+                  stck.pop_back();
+              }
+              catch(INTERP_KERNEL::Exception& e)
+              {
+                  std::ostringstream oss; oss << "For tuple # " << i << " with value (";
+                  std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
+                  oss << ") : Evaluation of function failed !" << e.what();
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+              }
+            }
         }
     }
-  return newArr;
+  return newArr.retn();
 }
 
-void DataArrayDouble::applyFuncFast32(const char *func)
+void DataArrayDouble::applyFuncFast32(const std::string& func)
 {
   checkAllocated();
   INTERP_KERNEL::ExprParser expr(func);
@@ -4490,7 +4624,7 @@ void DataArrayDouble::applyFuncFast32(const char *func)
   declareAsNew();
 }
 
-void DataArrayDouble::applyFuncFast64(const char *func)
+void DataArrayDouble::applyFuncFast64(const std::string& func)
 {
   checkAllocated();
   INTERP_KERNEL::ExprParser expr(func);
@@ -4525,8 +4659,10 @@ DataArrayDoubleIterator *DataArrayDouble::iterator()
  *
  *  \sa DataArrayDouble::getIdsNotInRange
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
+ *  \endif
  */
 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const
 {
@@ -4705,7 +4841,7 @@ DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *
   int k=0;
   for(int i=0;i<(int)a.size();i++)
     for(int j=0;j<nbc[i];j++,k++)
-      ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
+      ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
   return ret;
 }
 
@@ -4749,8 +4885,8 @@ DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArray
         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
       retPtr[i]=sum;
     }
-  ret->setInfoOnComponent(0,a1->getInfoOnComponent(0).c_str());
-  ret->setName(a1->getName().c_str());
+  ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
+  ret->setName(a1->getName());
   return ret;
 }
 
@@ -5544,6 +5680,37 @@ void DataArrayDouble::powEqual(const DataArrayDouble *other)
   declareAsNew();
 }
 
+/*!
+ * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
+ * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
+ * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
+ *
+ * \throw if \a this is not allocated.
+ * \throw if \a this has not exactly one component.
+ */
+std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
+  int nbt(getNumberOfTuples());
+  std::vector<bool> ret(nbt);
+  const double *pt(begin());
+  for(int i=0;i<nbt;i++)
+    {
+      if(fabs(pt[i])<eps)
+        ret[i]=false;
+      else if(fabs(pt[i]-1.)<eps)
+        ret[i]=true;
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  return ret;
+}
+
 /*!
  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
  * Server side.
@@ -5605,12 +5772,12 @@ bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI
  */
 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
 {
-  setName(tinyInfoS[0].c_str());
+  setName(tinyInfoS[0]);
   if(isAllocated())
     {
       int nbOfCompo=getNumberOfComponents();
       for(int i=0;i<nbOfCompo;i++)
-        setInfoOnComponent(i,tinyInfoS[i+1].c_str());
+        setInfoOnComponent(i,tinyInfoS[i+1]);
     }
 }
 
@@ -6028,7 +6195,7 @@ std::string DataArrayInt::reprZip() const
   return ret.str();
 }
 
-void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile, DataArrayByte *byteArr) const
+void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
 {
   static const char SPACE[4]={' ',' ',' ',' '};
   checkAllocated();
@@ -6093,7 +6260,7 @@ void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
   _mem.reprZip(getNumberOfComponents(),stream);
 }
 
-void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
+void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
 {
   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
   const int *data=getConstPointer();
@@ -6247,8 +6414,8 @@ void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd
  *  \throw If any value of \a this is not less than \a arrEnd[-1].
  */
 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
-                                     DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
-{
+                                     DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
+    {
   checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
@@ -6291,7 +6458,7 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
   castArr=ret1.retn();
   rankInsideCast=ret2.retn();
   castsPresent=ret3.retn();
-}
+    }
 
 /*!
  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
@@ -6353,8 +6520,10 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int
  *          The caller is to delete this result array using decrRef() as it is no more
  *          needed.
  * 
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
+ *  \endif
  */
 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
 {
@@ -6418,9 +6587,11 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
  *          The caller is to delete this result array using decrRef() as it is no more
  *          needed.
  * 
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
  *
  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
+ *  \endif
  */
 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
 {
@@ -6435,7 +6606,7 @@ DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
     {
       int v(new2Old[i]);
       if(v>=0 && v<oldNbOfElem)
-         pt[v]=i;
+        pt[v]=i;
       else
         {
           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
@@ -6720,9 +6891,11 @@ void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
  *  \throw If \a other includes a value which is not in \a this array.
  * 
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
  *
  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
+ *  \endif
  */
 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
 {
@@ -7568,10 +7741,10 @@ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue)
       for(;j<newNbOfComp;j++)
         nc[newNbOfComp*i+j]=dftValue;
     }
-  ret->setName(getName().c_str());
+  ret->setName(getName());
   for(int i=0;i<dim;i++)
-    ret->setInfoOnComponent(i,getInfoOnComponent(i).c_str());
-  ret->setName(getName().c_str());
+    ret->setInfoOnComponent(i,getInfoOnComponent(i));
+  ret->setName(getName());
   return ret.retn();
 }
 
@@ -7605,9 +7778,11 @@ void DataArrayInt::reAlloc(int nbOfTuples)
  *  \throw If a component index (\a i) is not valid: 
  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
+ *  \endif
  */
-DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
+DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const
 {
   checkAllocated();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
@@ -7634,9 +7809,11 @@ DataArray *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds
  *  \throw If \a this is not allocated.
  *  \throw If \a this and \a other arrays have different number of tuples.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
  *
  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
+ *  \endif
  */
 void DataArrayInt::meldWith(const DataArrayInt *other)
 {
@@ -7677,7 +7854,9 @@ void DataArrayInt::meldWith(const DataArrayInt *other)
  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
+ *  \endif
  */
 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
 {
@@ -7728,7 +7907,9 @@ void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vecto
  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
+ *  \endif
  */
 void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
 {
@@ -7791,7 +7972,9 @@ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int end
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
+ *  \endif
  */
 void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
 {
@@ -7846,7 +8029,9 @@ void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, in
  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
+ *  \endif
  */
 void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
 {
@@ -7917,7 +8102,9 @@ void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples,
  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
  *         out of a valid range for \a this array.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
+ *  \endif
  */
 void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
 {
@@ -7977,7 +8164,9 @@ void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
+ *  \endif
  */
 void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
 {
@@ -8049,7 +8238,9 @@ void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples,
  *            non-empty range of increasing indices or indices are out of a valid range
  *            for \this array.
  *
+ *  \if ENABLE_EXAMPLES
  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
+ *  \endif
  */
 void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
 {
@@ -8389,7 +8580,7 @@ DataArrayIntIterator *DataArrayInt::iterator()
 
 /*!
  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
- * given one.
+ * given one. The ids are sorted in the ascending order.
  *  \param [in] val - the value to find within \a this.
  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
  *          array using decrRef() as it is no more needed.
@@ -9407,7 +9598,7 @@ DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
   int k=0;
   for(int i=0;i<(int)a.size();i++)
     for(int j=0;j<nbc[i];j++,k++)
-      ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j).c_str());
+      ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
   return ret;
 }
 
@@ -9564,12 +9755,82 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayI
       else
         r=s1;
     }
-  DataArrayInt *ret=DataArrayInt::New();
+  DataArrayInt *ret(DataArrayInt::New());
   ret->alloc((int)r.size(),1);
   std::copy(r.begin(),r.end(),ret->getPointer());
   return ret;
 }
 
+/// @cond INTERNAL
+namespace ParaMEDMEMImpl
+{
+  class OpSwitchedOn
+  {
+  public:
+    OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
+    void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
+  private:
+    int *_pt;
+    int _cnt;
+  };
+
+  class OpSwitchedOff
+  {
+  public:
+    OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
+    void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
+  private:
+    int *_pt;
+    int _cnt;
+  };
+}
+/// @endcond
+
+/*!
+ * This method returns the list of ids in ascending mode so that v[id]==true.
+ */
+DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
+{
+  int sz((int)std::count(v.begin(),v.end(),true));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
+  std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer()));
+  return ret.retn();
+}
+
+/*!
+ * This method returns the list of ids in ascending mode so that v[id]==false.
+ */
+DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
+{
+  int sz((int)std::count(v.begin(),v.end(),false));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
+  std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer()));
+  return ret.retn();
+}
+
+/*!
+ * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
+ * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
+ *
+ * \param [in] v the input data structure to be translate into skyline format.
+ * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
+ * \param [out] dataIndex the second element of the skyline format.
+ */
+void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
+{
+  int sz((int)v.size());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
+  ret1->alloc(sz+1,1);
+  int *pt(ret1->getPointer()); *pt=0;
+  for(int i=0;i<sz;i++,pt++)
+    pt[1]=pt[0]+(int)v[i].size();
+  ret0->alloc(ret1->back(),1);
+  pt=ret0->getPointer();
+  for(int i=0;i<sz;i++)
+    pt=std::copy(v[i].begin(),v[i].end(),pt);
+  data=ret0.retn(); dataIndex=ret1.retn();
+}
+
 /*!
  * Returns a new DataArrayInt which contains a complement of elements of \a this
  * one-dimensional array. I.e. the result array contains all elements from the range [0,
@@ -9584,26 +9845,26 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayI
  */
 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
 {
-   checkAllocated();
-   if(getNumberOfComponents()!=1)
-     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
-   std::vector<bool> tmp(nbOfElement);
-   const int *pt=getConstPointer();
-   int nbOfTuples=getNumberOfTuples();
-   for(const int *w=pt;w!=pt+nbOfTuples;w++)
-     if(*w>=0 && *w<nbOfElement)
-       tmp[*w]=true;
-     else
-       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
-   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
-   DataArrayInt *ret=DataArrayInt::New();
-   ret->alloc(nbOfRetVal,1);
-   int j=0;
-   int *retPtr=ret->getPointer();
-   for(int i=0;i<nbOfElement;i++)
-     if(!tmp[i])
-       retPtr[j++]=i;
-   return ret;
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
+  std::vector<bool> tmp(nbOfElement);
+  const int *pt=getConstPointer();
+  int nbOfTuples=getNumberOfTuples();
+  for(const int *w=pt;w!=pt+nbOfTuples;w++)
+    if(*w>=0 && *w<nbOfElement)
+      tmp[*w]=true;
+    else
+      throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
+  int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbOfRetVal,1);
+  int j=0;
+  int *retPtr=ret->getPointer();
+  for(int i=0;i<nbOfElement;i++)
+    if(!tmp[i])
+      retPtr[j++]=i;
+  return ret;
 }
 
 /*!
@@ -9626,9 +9887,9 @@ DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
   checkAllocated();
   other->checkAllocated();
   if(getNumberOfComponents()!=1)
-     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
   if(other->getNumberOfComponents()!=1)
-     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
   const int *pt=getConstPointer();
   int nbOfTuples=getNumberOfTuples();
   std::set<int> s1(pt,pt+nbOfTuples);
@@ -9658,7 +9919,8 @@ DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other
   checkAllocated(); other->checkAllocated();
   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
-  const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
+  const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
+  const int *work1(pt1Bg),*work2(pt2Bg);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
   for(;work1!=pt1End;work1++)
     {
@@ -9720,7 +9982,7 @@ DataArrayInt *DataArrayInt::buildUnique() const
 {
   checkAllocated();
   if(getNumberOfComponents()!=1)
-     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
   int nbOfTuples=getNumberOfTuples();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
   int *data=tmp->getPointer();
@@ -9757,7 +10019,7 @@ DataArrayInt *DataArrayInt::deltaShiftIndex() const
 {
   checkAllocated();
   if(getNumberOfComponents()!=1)
-     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
+    throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
   int nbOfTuples=getNumberOfTuples();
   if(nbOfTuples<2)
     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
@@ -9790,7 +10052,7 @@ void DataArrayInt::computeOffsets()
 {
   checkAllocated();
   if(getNumberOfComponents()!=1)
-     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
+    throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
   int nbOfTuples=getNumberOfTuples();
   if(nbOfTuples==0)
     return ;
@@ -9924,10 +10186,10 @@ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets
     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
   checkAllocated();
   if(getNumberOfComponents()!=1)
-     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
   offsets->checkAllocated();
   if(offsets->getNumberOfComponents()!=1)
-     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
   int othNbTuples=offsets->getNumberOfTuples()-1;
   int nbOfTuples=getNumberOfTuples();
   int retNbOftuples=0;
@@ -10859,7 +11121,7 @@ void DataArrayInt::divideEqual(const DataArrayInt *other)
  */
 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
 {
-    if(!a1 || !a2)
+  if(!a1 || !a2)
     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
   int nbOfTuple1=a1->getNumberOfTuples();
   int nbOfTuple2=a2->getNumberOfTuples();
@@ -11192,12 +11454,12 @@ bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
  */
 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
 {
-  setName(tinyInfoS[0].c_str());
+  setName(tinyInfoS[0]);
   if(isAllocated())
     {
       int nbOfCompo=tinyInfoI[1];
       for(int i=0;i<nbOfCompo;i++)
-        setInfoOnComponent(i,tinyInfoS[i+1].c_str());
+        setInfoOnComponent(i,tinyInfoS[i+1]);
     }
 }