Salome HOME
2557bc4421985d934cc0aa172e3461a383f7d5b3
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArrayChar.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MCAuto.hxx"
23
24 #include <set>
25 #include <cmath>
26 #include <limits>
27 #include <numeric>
28 #include <algorithm>
29 #include <functional>
30
31 using namespace MEDCoupling;
32
33 template class DataArrayTemplate<char>;
34
35 /*!
36  * Returns an integer value characterizing \a this array, which is useful for a quick
37  * comparison of many instances of DataArrayInt.
38  *  \return int - the hash value.
39  *  \throw If \a this is not allocated.
40  */
41 int DataArrayChar::getHashCode() const
42 {
43   checkAllocated();
44   std::size_t nbOfElems=getNbOfElems();
45   int ret=nbOfElems*65536;
46   int delta=3;
47   if(nbOfElems>48)
48     delta=nbOfElems/8;
49   int ret0=0;
50   const char *pt=begin();
51   for(std::size_t i=0;i<nbOfElems;i+=delta)
52     ret0+=pt[i];
53   return ret+ret0;
54 }
55
56 /*!
57  * Checks if \a this and another DataArrayChar are fully equal. For more info see
58  * \ref MEDCouplingArrayBasicsCompare.
59  *  \param [in] other - an instance of DataArrayChar to compare with \a this one.
60  *  \return bool - \a true if the two arrays are equal, \a false else.
61  */
62 bool DataArrayChar::isEqual(const DataArrayChar& other) const
63 {
64   std::string tmp;
65   return isEqualIfNotWhy(other,tmp);
66 }
67
68 /*!
69  * Equivalent to DataArrayChar::isEqual except that if false the reason of
70  * mismatch is given.
71  * 
72  * \param [in] other the instance to be compared with \a this
73  * \param [out] reason In case of inequality returns the reason.
74  * \sa DataArrayChar::isEqual
75  */
76 bool DataArrayChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
77 {
78   if(!areInfoEqualsIfNotWhy(other,reason))
79     return false;
80   return _mem.isEqual(other._mem,0,reason);
81 }
82
83 /*!
84  * Checks if values of \a this and another DataArrayChar are equal. For more info see
85  * \ref MEDCouplingArrayBasicsCompare.
86  *  \param [in] other - an instance of DataArrayChar to compare with \a this one.
87  *  \return bool - \a true if the values of two arrays are equal, \a false else.
88  */
89 bool DataArrayChar::isEqualWithoutConsideringStr(const DataArrayChar& other) const
90 {
91   std::string tmp;
92   return _mem.isEqual(other._mem,0,tmp);
93 }
94
95 /*!
96  * Assign zero to all values in \a this array. To know more on filling arrays see
97  * \ref MEDCouplingArrayFill.
98  * \throw If \a this is not allocated.
99  */
100 void DataArrayChar::fillWithZero()
101 {
102   fillWithValue(0);
103 }
104
105 /*!
106  * Returns a textual and human readable representation of \a this instance of
107  * DataArrayChar. This text is shown when a DataArrayChar is printed in Python.
108  *  \return std::string - text describing \a this DataArrayChar.
109  */
110 std::string DataArrayChar::repr() const
111 {
112   std::ostringstream ret;
113   reprStream(ret);
114   return ret.str();
115 }
116
117 std::string DataArrayChar::reprZip() const
118 {
119   std::ostringstream ret;
120   reprZipStream(ret);
121   return ret.str();
122 }
123
124 /*!
125  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
126  * array to the new one.
127  *  \return DataArrayInt * - the new instance of DataArrayChar.
128  */
129 DataArrayInt *DataArrayChar::convertToIntArr() const
130 {
131   checkAllocated();
132   DataArrayInt *ret=DataArrayInt::New();
133   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
134   std::size_t nbOfVals=getNbOfElems();
135   const char *src=getConstPointer();
136   int *dest=ret->getPointer();
137   std::copy(src,src+nbOfVals,dest);
138   ret->copyStringInfoFrom(*this);
139   return ret;
140 }
141
142 /*!
143  * Returns a copy of \a this array with values permuted as required by \a new2Old array.
144  * The values are permuted so that  \c new[ i ] = \c old[ \a new2Old[ i ]]. Number of
145  * tuples in the result array remains the same as in \this one.
146  * If a permutation reduction is needed, subArray() or selectByTupleId() should be used.
147  * For more info on renumbering see \ref numbering.
148  *  \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples()
149  *     giving a previous position of i-th new value.
150  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
151  *          is to delete using decrRef() as it is no more needed.
152  */
153 DataArrayChar *DataArrayChar::renumberR(const int *new2Old) const
154 {
155   checkAllocated();
156   int nbTuples=getNumberOfTuples();
157   int nbOfCompo=getNumberOfComponents();
158   MCAuto<DataArrayChar> ret=buildEmptySpecializedDAChar();
159   ret->alloc(nbTuples,nbOfCompo);
160   ret->copyStringInfoFrom(*this);
161   const char *iptr=getConstPointer();
162   char *optr=ret->getPointer();
163   for(int i=0;i<nbTuples;i++)
164     std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i);
165   ret->copyStringInfoFrom(*this);
166   return ret.retn();
167 }
168
169 /*!
170  * Returns a shorten and permuted copy of \a this array. The new DataArrayChar is
171  * of size \a newNbOfTuple and it's values are permuted as required by \a old2New array.
172  * The values are permuted so that  \c new[ \a old2New[ i ]] = \c old[ i ] for all
173  * \a old2New[ i ] >= 0. In other words every i-th tuple in \a this array, for which 
174  * \a old2New[ i ] is negative, is missing from the result array.
175  * For more info on renumbering see \ref numbering.
176  *  \param [in] old2New - C array of length equal to \a this->getNumberOfTuples()
177  *     giving a new position for i-th old tuple and giving negative position for
178  *     for i-th old tuple that should be omitted.
179  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
180  *          is to delete using decrRef() as it is no more needed.
181  */
182 DataArrayChar *DataArrayChar::renumberAndReduce(const int *old2New, int newNbOfTuple) const
183 {
184   checkAllocated();
185   int nbTuples=getNumberOfTuples();
186   int nbOfCompo=getNumberOfComponents();
187   MCAuto<DataArrayChar> ret=buildEmptySpecializedDAChar();
188   ret->alloc(newNbOfTuple,nbOfCompo);
189   const char *iptr=getConstPointer();
190   char *optr=ret->getPointer();
191   for(int i=0;i<nbTuples;i++)
192     {
193       int w=old2New[i];
194       if(w>=0)
195         std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo);
196     }
197   ret->copyStringInfoFrom(*this);
198   return ret.retn();
199 }
200
201 /*!
202  * Returns a shorten and permuted copy of \a this array. The new DataArrayChar is
203  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
204  * \a new2OldBg array.
205  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
206  * This method is equivalent to renumberAndReduce() except that convention in input is
207  * \c new2old and \b not \c old2new.
208  * For more info on renumbering see \ref numbering.
209  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
210  *              tuple index in \a this array to fill the i-th tuple in the new array.
211  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
212  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
213  *              \a new2OldBg <= \a pi < \a new2OldEnd.
214  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
215  *          is to delete using decrRef() as it is no more needed.
216  */
217 DataArrayChar *DataArrayChar::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
218 {
219   return selectByTupleIdSafe(new2OldBg,new2OldEnd);
220 }
221
222 /*!
223  * Returns a shorten and permuted copy of \a this array. The new DataArrayChar is
224  * of size \a new2OldEnd - \a new2OldBg and it's values are permuted as required by
225  * \a new2OldBg array.
226  * The values are permuted so that  \c new[ i ] = \c old[ \a new2OldBg[ i ]].
227  * This method is equivalent to renumberAndReduce() except that convention in input is
228  * \c new2old and \b not \c old2new.
229  * This method is equivalent to selectByTupleId() except that it prevents coping data
230  * from behind the end of \a this array.
231  * For more info on renumbering see \ref numbering.
232  *  \param [in] new2OldBg - pointer to the beginning of a permutation array that gives a
233  *              tuple index in \a this array to fill the i-th tuple in the new array.
234  *  \param [in] new2OldEnd - specifies the end of the permutation array that starts at
235  *              \a new2OldBg, so that pointer to a tuple index (\a pi) varies as this:
236  *              \a new2OldBg <= \a pi < \a new2OldEnd.
237  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
238  *          is to delete using decrRef() as it is no more needed.
239  *  \throw If \a new2OldEnd - \a new2OldBg > \a this->getNumberOfTuples().
240  */
241 DataArrayChar *DataArrayChar::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const
242 {
243   checkAllocated();
244   MCAuto<DataArrayChar> ret=buildEmptySpecializedDAChar();
245   int nbComp=getNumberOfComponents();
246   int oldNbOfTuples=getNumberOfTuples();
247   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
248   ret->copyStringInfoFrom(*this);
249   char *pt=ret->getPointer();
250   const char *srcPt=getConstPointer();
251   int i=0;
252   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
253     if(*w>=0 && *w<oldNbOfTuples)
254       std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
255     else
256       throw INTERP_KERNEL::Exception("DataArrayChar::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
257   ret->copyStringInfoFrom(*this);
258   return ret.retn();
259 }
260
261 /*!
262  * Returns a shorten copy of \a this array. The new DataArrayChar contains every
263  * (\a bg + \c i * \a step)-th tuple of \a this array located before the \a end2-th
264  * tuple. Indices of the selected tuples are the same as ones returned by the Python
265  * command \c range( \a bg, \a end2, \a step ).
266  * This method is equivalent to selectByTupleIdSafe() except that the input array is
267  * not constructed explicitly.
268  * For more info on renumbering see \ref numbering.
269  *  \param [in] bg - index of the first tuple to copy from \a this array.
270  *  \param [in] end2 - index of the tuple before which the tuples to copy are located.
271  *  \param [in] step - index increment to get index of the next tuple to copy.
272  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
273  *          is to delete using decrRef() as it is no more needed.
274  *  \throw If (\a end2 < \a bg) or (\a step <= 0).
275  *  \sa DataArrayChar::substr.
276  */
277 DataArrayChar *DataArrayChar::selectByTupleIdSafeSlice(int bg, int end2, int step) const
278 {
279   checkAllocated();
280   MCAuto<DataArrayChar> ret=buildEmptySpecializedDAChar();
281   int nbComp=getNumberOfComponents();
282   int newNbOfTuples=GetNumberOfItemGivenBESRelative(bg,end2,step,"DataArrayInt::selectByTupleIdSafeSlice : ");
283   ret->alloc(newNbOfTuples,nbComp);
284   char *pt=ret->getPointer();
285   const char *srcPt=getConstPointer()+bg*nbComp;
286   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
287     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
288   ret->copyStringInfoFrom(*this);
289   return ret.retn();
290 }
291
292 /*!
293  * Checks if all values in \a this array are equal to \a val.
294  *  \param [in] val - value to check equality of array values to.
295  *  \return bool - \a true if all values are \a val.
296  *  \throw If \a this is not allocated.
297  *  \throw If \a this->getNumberOfComponents() != 1
298  */
299 bool DataArrayChar::isUniform(char val) const
300 {
301   checkAllocated();
302   if(getNumberOfComponents()!=1)
303     throw INTERP_KERNEL::Exception("DataArrayChar::isUniform : must be applied on DataArrayChar with only one component, you can call 'rearrange' method before !");
304   int nbOfTuples=getNumberOfTuples();
305   const char *w=getConstPointer();
306   const char *end2=w+nbOfTuples;
307   for(;w!=end2;w++)
308     if(*w!=val)
309       return false;
310   return true;
311 }
312
313 /*!
314  * Changes the number of components within \a this array so that its raw data **does
315  * not** change, instead splitting this data into tuples changes.
316  *  \param [in] newNbOfComp - number of components for \a this array to have.
317  *  \throw If \a this is not allocated
318  *  \throw If getNbOfElems() % \a newNbOfCompo != 0.
319  *  \throw If \a newNbOfCompo is lower than 1.
320  *  \throw If the rearrange method would lead to a number of tuples higher than 2147483647 (maximal capacity of int32 !).
321  *  \warning This method erases all (name and unit) component info set before!
322  */
323 void DataArrayChar::rearrange(int newNbOfCompo)
324 {
325   checkAllocated();
326   if(newNbOfCompo<1)
327     throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : input newNbOfCompo must be > 0 !");
328   std::size_t nbOfElems=getNbOfElems();
329   if(nbOfElems%newNbOfCompo!=0)
330     throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : nbOfElems%newNbOfCompo!=0 !");
331   if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::max())
332     throw INTERP_KERNEL::Exception("DataArrayChar::rearrange : the rearrangement leads to too high number of tuples (> 2147483647) !");
333   _info_on_compo.clear();
334   _info_on_compo.resize(newNbOfCompo);
335   declareAsNew();
336 }
337
338 /*!
339  * Returns a shorten copy of \a this array. The new DataArrayChar contains all
340  * tuples starting from the \a tupleIdBg-th tuple and including all tuples located before
341  * the \a tupleIdEnd-th one. This methods has a similar behavior as std::string::subArray().
342  * This method is a specialization of selectByTupleIdSafeSlice().
343  *  \param [in] tupleIdBg - index of the first tuple to copy from \a this array.
344  *  \param [in] tupleIdEnd - index of the tuple before which the tuples to copy are located.
345  *          If \a tupleIdEnd == -1, all the tuples till the end of \a this array are copied.
346  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
347  *          is to delete using decrRef() as it is no more needed.
348  *  \throw If \a tupleIdBg < 0.
349  *  \throw If \a tupleIdBg > \a this->getNumberOfTuples().
350     \throw If \a tupleIdEnd != -1 && \a tupleIdEnd < \a this->getNumberOfTuples().
351  *  \sa DataArrayChar::selectByTupleIdSafeSlice
352  */
353 DataArrayChar *DataArrayChar::subArray(int tupleIdBg, int tupleIdEnd) const
354 {
355   checkAllocated();
356   int nbt=getNumberOfTuples();
357   if(tupleIdBg<0)
358     throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter must be greater than 0 !");
359   if(tupleIdBg>nbt)
360     throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter is greater than number of tuples !");
361   int trueEnd=tupleIdEnd;
362   if(tupleIdEnd!=-1)
363     {
364       if(tupleIdEnd>nbt)
365         throw INTERP_KERNEL::Exception("DataArrayChar::substr : The tupleIdBg parameter is greater or equal than number of tuples !");
366     }
367   else
368     trueEnd=nbt;
369   int nbComp=getNumberOfComponents();
370   MCAuto<DataArrayChar> ret=buildEmptySpecializedDAChar();
371   ret->alloc(trueEnd-tupleIdBg,nbComp);
372   ret->copyStringInfoFrom(*this);
373   std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer());
374   return ret.retn();
375 }
376
377 /*!
378  * Returns a shorten or extended copy of \a this array. If \a newNbOfComp is less
379  * than \a this->getNumberOfComponents() then the result array is shorten as each tuple
380  * is truncated to have \a newNbOfComp components, keeping first components. If \a
381  * newNbOfComp is more than \a this->getNumberOfComponents() then the result array is
382  * expanded as each tuple is populated with \a dftValue to have \a newNbOfComp
383  * components.  
384  *  \param [in] newNbOfComp - number of components for the new array to have.
385  *  \param [in] dftValue - value assigned to new values added to the new array.
386  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
387  *          is to delete using decrRef() as it is no more needed.
388  *  \throw If \a this is not allocated.
389  */
390 DataArrayChar *DataArrayChar::changeNbOfComponents(int newNbOfComp, char dftValue) const
391 {
392   checkAllocated();
393   MCAuto<DataArrayChar> ret=buildEmptySpecializedDAChar();
394   ret->alloc(getNumberOfTuples(),newNbOfComp);
395   const char *oldc=getConstPointer();
396   char *nc=ret->getPointer();
397   int nbOfTuples=getNumberOfTuples();
398   int oldNbOfComp=getNumberOfComponents();
399   int dim=std::min(oldNbOfComp,newNbOfComp);
400   for(int i=0;i<nbOfTuples;i++)
401     {
402       int j=0;
403       for(;j<dim;j++)
404         nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j];
405       for(;j<newNbOfComp;j++)
406         nc[newNbOfComp*i+j]=dftValue;
407     }
408   ret->setName(getName());
409   for(int i=0;i<dim;i++)
410     ret->setInfoOnComponent(i,getInfoOnComponent(i));
411   ret->setName(getName());
412   return ret.retn();
413 }
414
415 /*!
416  * Returns a copy of \a this array composed of selected components.
417  * The new DataArrayChar has the same number of tuples but includes components
418  * specified by \a compoIds parameter. So that getNbOfElems() of the result array
419  * can be either less, same or more than \a this->getNbOfElems().
420  *  \param [in] compoIds - sequence of zero based indices of components to include
421  *              into the new array.
422  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
423  *          is to delete using decrRef() as it is no more needed.
424  *  \throw If \a this is not allocated.
425  *  \throw If a component index (\a i) is not valid: 
426  *         \a i < 0 || \a i >= \a this->getNumberOfComponents().
427  *
428  *  \if ENABLE_EXAMPLES
429  *  \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example".
430  *  \endif
431  */
432 DataArrayChar *DataArrayChar::keepSelectedComponents(const std::vector<int>& compoIds) const
433 {
434   checkAllocated();
435   MCAuto<DataArrayChar> ret(buildEmptySpecializedDAChar());
436   int newNbOfCompo=(int)compoIds.size();
437   int oldNbOfCompo=getNumberOfComponents();
438   for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++)
439     DataArray::CheckValueInRange(oldNbOfCompo,(*it),"keepSelectedComponents invalid requested component");
440   int nbOfTuples=getNumberOfTuples();
441   ret->alloc(nbOfTuples,newNbOfCompo);
442   ret->copyPartOfStringInfoFrom(*this,compoIds);
443   const char *oldc=getConstPointer();
444   char *nc=ret->getPointer();
445   for(int i=0;i<nbOfTuples;i++)
446     for(int j=0;j<newNbOfCompo;j++,nc++)
447       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
448   return ret.retn();
449 }
450
451 /*!
452  * Appends components of another array to components of \a this one, tuple by tuple.
453  * So that the number of tuples of \a this array remains the same and the number of 
454  * components increases.
455  *  \param [in] other - the DataArrayChar to append to \a this one.
456  *  \throw If \a this is not allocated.
457  *  \throw If \a this and \a other arrays have different number of tuples.
458  *
459  *  \if ENABLE_EXAMPLES
460  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
461  *
462  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
463  *  \endif
464  */
465 void DataArrayChar::meldWith(const DataArrayChar *other)
466 {
467   if(!other)
468     throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : DataArrayChar pointer in input is NULL !");
469   checkAllocated();
470   other->checkAllocated();
471   int nbOfTuples=getNumberOfTuples();
472   if(nbOfTuples!=other->getNumberOfTuples())
473     throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : mismatch of number of tuples !");
474   int nbOfComp1=getNumberOfComponents();
475   int nbOfComp2=other->getNumberOfComponents();
476   char *newArr=(char *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(char));
477   char *w=newArr;
478   const char *inp1=getConstPointer();
479   const char *inp2=other->getConstPointer();
480   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
481     {
482       w=std::copy(inp1,inp1+nbOfComp1,w);
483       w=std::copy(inp2,inp2+nbOfComp2,w);
484     }
485   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
486   std::vector<int> compIds(nbOfComp2);
487   for(int i=0;i<nbOfComp2;i++)
488     compIds[i]=nbOfComp1+i;
489   copyPartOfStringInfoFrom2(compIds,*other);
490 }
491
492 /*!
493  * Copy all values from another DataArrayChar into specified tuples and components
494  * of \a this array. Textual data is not copied.
495  * The tree parameters defining set of indices of tuples and components are similar to
496  * the tree parameters of the Python function \c range(\c start,\c stop,\c step).
497  *  \param [in] a - the array to copy values from.
498  *  \param [in] bgTuples - index of the first tuple of \a this array to assign values to.
499  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
500  *              are located.
501  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
502  *  \param [in] bgComp - index of the first component of \a this array to assign values to.
503  *  \param [in] endComp - index of the component before which the components to assign
504  *              to are located.
505  *  \param [in] stepComp - index increment to get index of the next component to assign to.
506  *  \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() 
507  *              must be equal to the number of columns to assign to, else an
508  *              exception is thrown; if \a false, then it is only required that \a
509  *              a->getNbOfElems() equals to number of values to assign to (this condition
510  *              must be respected even if \a strictCompoCompare is \a true). The number of 
511  *              values to assign to is given by following Python expression:
512  *              \a nbTargetValues = 
513  *              \c len(\c range(\a bgTuples,\a endTuples,\a stepTuples)) *
514  *              \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
515  *  \throw If \a a is NULL.
516  *  \throw If \a a is not allocated.
517  *  \throw If \a this is not allocated.
518  *  \throw If parameters specifying tuples and components to assign to do not give a
519  *            non-empty range of increasing indices.
520  *  \throw If \a a->getNbOfElems() != \a nbTargetValues.
521  *  \throw If \a strictCompoCompare == \a true && \a a->getNumberOfComponents() !=
522  *            \c len(\c range(\a bgComp,\a endComp,\a stepComp)).
523  *
524  *  \if ENABLE_EXAMPLES
525  *  \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example".
526  *  \endif
527  */
528 void DataArrayChar::setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
529 {
530   if(!a)
531     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues1 : DataArrayChar pointer in input is NULL !");
532   const char msg[]="DataArrayChar::setPartOfValues1";
533   checkAllocated();
534   a->checkAllocated();
535   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
536   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
537   int nbComp=getNumberOfComponents();
538   int nbOfTuples=getNumberOfTuples();
539   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
540   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
541   bool assignTech=true;
542   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
543     {
544       if(strictCompoCompare)
545         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
546     }
547   else
548     {
549       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
550       assignTech=false;
551     }
552   char *pt=getPointer()+bgTuples*nbComp+bgComp;
553   const char *srcPt=a->getConstPointer();
554   if(assignTech)
555     {
556       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
557         for(int j=0;j<newNbOfComp;j++,srcPt++)
558           pt[j*stepComp]=*srcPt;
559     }
560   else
561     {
562       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
563         {
564           const char *srcPt2=srcPt;
565           for(int j=0;j<newNbOfComp;j++,srcPt2++)
566             pt[j*stepComp]=*srcPt2;
567         }
568     }
569 }
570
571 /*!
572  * Assign a given value to values at specified tuples and components of \a this array.
573  * The tree parameters defining set of indices of tuples and components are similar to
574  * the tree parameters of the Python function \c range(\c start,\c stop,\c step)..
575  *  \param [in] a - the value to assign.
576  *  \param [in] bgTuples - index of the first tuple of \a this array to assign to.
577  *  \param [in] endTuples - index of the tuple before which the tuples to assign to
578  *              are located.
579  *  \param [in] stepTuples - index increment to get index of the next tuple to assign to.
580  *  \param [in] bgComp - index of the first component of \a this array to assign to.
581  *  \param [in] endComp - index of the component before which the components to assign
582  *              to are located.
583  *  \param [in] stepComp - index increment to get index of the next component to assign to.
584  *  \throw If \a this is not allocated.
585  *  \throw If parameters specifying tuples and components to assign to, do not give a
586  *            non-empty range of increasing indices or indices are out of a valid range
587  *            for \this array.
588  *
589  *  \if ENABLE_EXAMPLES
590  *  \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example".
591  *  \endif
592  */
593 void DataArrayChar::setPartOfValuesSimple1(char a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp)
594 {
595   const char msg[]="DataArrayChar::setPartOfValuesSimple1";
596   checkAllocated();
597   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
598   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
599   int nbComp=getNumberOfComponents();
600   int nbOfTuples=getNumberOfTuples();
601   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
602   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
603   char *pt=getPointer()+bgTuples*nbComp+bgComp;
604   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
605     for(int j=0;j<newNbOfComp;j++)
606       pt[j*stepComp]=a;
607 }
608
609
610 /*!
611  * Copy all values from another DataArrayChar (\a a) into specified tuples and 
612  * components of \a this array. Textual data is not copied.
613  * The tuples and components to assign to are defined by C arrays of indices.
614  * There are two *modes of usage*:
615  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
616  *   of \a a is assigned to its own location within \a this array. 
617  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
618  *   components of every specified tuple of \a this array. In this mode it is required
619  *   that \a a->getNumberOfComponents() equals to the number of specified components.
620  * 
621  *  \param [in] a - the array to copy values from.
622  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
623  *              assign values of \a a to.
624  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
625  *              pointer to a tuple index <em>(pi)</em> varies as this: 
626  *              \a bgTuples <= \a pi < \a endTuples.
627  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
628  *              assign values of \a a to.
629  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
630  *              pointer to a component index <em>(pi)</em> varies as this: 
631  *              \a bgComp <= \a pi < \a endComp.
632  *  \param [in] strictCompoCompare - this parameter is checked only if the
633  *               *mode of usage* is the first; if it is \a true (default), 
634  *               then \a a->getNumberOfComponents() must be equal 
635  *               to the number of specified columns, else this is not required.
636  *  \throw If \a a is NULL.
637  *  \throw If \a a is not allocated.
638  *  \throw If \a this is not allocated.
639  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
640  *         out of a valid range for \a this array.
641  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
642  *         if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>.
643  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
644  *         <em> a->getNumberOfComponents() != (endComp - bgComp)</em>.
645  *
646  *  \if ENABLE_EXAMPLES
647  *  \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example".
648  *  \endif
649  */
650 void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
651 {
652   if(!a)
653     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues2 : DataArrayChar pointer in input is NULL !");
654   const char msg[]="DataArrayChar::setPartOfValues2";
655   checkAllocated();
656   a->checkAllocated();
657   int nbComp=getNumberOfComponents();
658   int nbOfTuples=getNumberOfTuples();
659   for(const int *z=bgComp;z!=endComp;z++)
660     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
661   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
662   int newNbOfComp=(int)std::distance(bgComp,endComp);
663   bool assignTech=true;
664   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
665     {
666       if(strictCompoCompare)
667         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
668     }
669   else
670     {
671       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
672       assignTech=false;
673     }
674   char *pt=getPointer();
675   const char *srcPt=a->getConstPointer();
676   if(assignTech)
677     {    
678       for(const int *w=bgTuples;w!=endTuples;w++)
679         {
680           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
681           for(const int *z=bgComp;z!=endComp;z++,srcPt++)
682             {    
683               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt;
684             }
685         }
686     }
687   else
688     {
689       for(const int *w=bgTuples;w!=endTuples;w++)
690         {
691           const char *srcPt2=srcPt;
692           DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
693           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
694             {    
695               pt[(std::size_t)(*w)*nbComp+(*z)]=*srcPt2;
696             }
697         }
698     }
699 }
700
701 /*!
702  * Assign a given value to values at specified tuples and components of \a this array.
703  * The tuples and components to assign to are defined by C arrays of indices.
704  *  \param [in] a - the value to assign.
705  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
706  *              assign \a a to.
707  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
708  *              pointer to a tuple index (\a pi) varies as this: 
709  *              \a bgTuples <= \a pi < \a endTuples.
710  *  \param [in] bgComp - pointer to an array of component indices of \a this array to
711  *              assign \a a to.
712  *  \param [in] endComp - specifies the end of the array \a bgTuples, so that
713  *              pointer to a component index (\a pi) varies as this: 
714  *              \a bgComp <= \a pi < \a endComp.
715  *  \throw If \a this is not allocated.
716  *  \throw If any index of tuple/component given by <em>bgTuples / bgComp</em> is
717  *         out of a valid range for \a this array.
718  *
719  *  \if ENABLE_EXAMPLES
720  *  \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example".
721  *  \endif
722  */
723 void DataArrayChar::setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp)
724 {
725   checkAllocated();
726   int nbComp=getNumberOfComponents();
727   int nbOfTuples=getNumberOfTuples();
728   for(const int *z=bgComp;z!=endComp;z++)
729     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
730   char *pt=getPointer();
731   for(const int *w=bgTuples;w!=endTuples;w++)
732     for(const int *z=bgComp;z!=endComp;z++)
733       {
734         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
735         pt[(std::size_t)(*w)*nbComp+(*z)]=a;
736       }
737 }
738
739 /*!
740  * Copy all values from another DataArrayChar (\a a) into specified tuples and 
741  * components of \a this array. Textual data is not copied.
742  * The tuples to assign to are defined by a C array of indices.
743  * The components to assign to are defined by three values similar to parameters of
744  * the Python function \c range(\c start,\c stop,\c step).
745  * There are two *modes of usage*:
746  * - If \a a->getNbOfElems() equals to number of values to assign to, then every value
747  *   of \a a is assigned to its own location within \a this array. 
748  * - If \a a includes one tuple, then all values of \a a are assigned to the specified
749  *   components of every specified tuple of \a this array. In this mode it is required
750  *   that \a a->getNumberOfComponents() equals to the number of specified components.
751  *
752  *  \param [in] a - the array to copy values from.
753  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
754  *              assign values of \a a to.
755  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
756  *              pointer to a tuple index <em>(pi)</em> varies as this: 
757  *              \a bgTuples <= \a pi < \a endTuples.
758  *  \param [in] bgComp - index of the first component of \a this array to assign to.
759  *  \param [in] endComp - index of the component before which the components to assign
760  *              to are located.
761  *  \param [in] stepComp - index increment to get index of the next component to assign to.
762  *  \param [in] strictCompoCompare - this parameter is checked only in the first
763  *               *mode of usage*; if \a strictCompoCompare is \a true (default), 
764  *               then \a a->getNumberOfComponents() must be equal 
765  *               to the number of specified columns, else this is not required.
766  *  \throw If \a a is NULL.
767  *  \throw If \a a is not allocated.
768  *  \throw If \a this is not allocated.
769  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
770  *         \a this array.
771  *  \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and
772  *         if <em> a->getNumberOfComponents()</em> is unequal to the number of components
773  *         defined by <em>(bgComp,endComp,stepComp)</em>.
774  *  \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or
775  *         <em> a->getNumberOfComponents()</em> is unequal to the number of components
776  *         defined by <em>(bgComp,endComp,stepComp)</em>.
777  *  \throw If parameters specifying components to assign to, do not give a
778  *            non-empty range of increasing indices or indices are out of a valid range
779  *            for \this array.
780  *
781  *  \if ENABLE_EXAMPLES
782  *  \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example".
783  *  \endif
784  */
785 void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
786 {
787   if(!a)
788     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValues3 : DataArrayChar pointer in input is NULL !");
789   const char msg[]="DataArrayChar::setPartOfValues3";
790   checkAllocated();
791   a->checkAllocated();
792   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
793   int nbComp=getNumberOfComponents();
794   int nbOfTuples=getNumberOfTuples();
795   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
796   int newNbOfTuples=(int)std::distance(bgTuples,endTuples);
797   bool assignTech=true;
798   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
799     {
800       if(strictCompoCompare)
801         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
802     }
803   else
804     {
805       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
806       assignTech=false;
807     }
808   char *pt=getPointer()+bgComp;
809   const char *srcPt=a->getConstPointer();
810   if(assignTech)
811     {
812       for(const int *w=bgTuples;w!=endTuples;w++)
813         for(int j=0;j<newNbOfComp;j++,srcPt++)
814           {
815             DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
816             pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt;
817           }
818     }
819   else
820     {
821       for(const int *w=bgTuples;w!=endTuples;w++)
822         {
823           const char *srcPt2=srcPt;
824           for(int j=0;j<newNbOfComp;j++,srcPt2++)
825             {
826               DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
827               pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2;
828             }
829         }
830     }
831 }
832
833 /*!
834  * Assign a given value to values at specified tuples and components of \a this array.
835  * The tuples to assign to are defined by a C array of indices.
836  * The components to assign to are defined by three values similar to parameters of
837  * the Python function \c range(\c start,\c stop,\c step).
838  *  \param [in] a - the value to assign.
839  *  \param [in] bgTuples - pointer to an array of tuple indices of \a this array to
840  *              assign \a a to.
841  *  \param [in] endTuples - specifies the end of the array \a bgTuples, so that
842  *              pointer to a tuple index <em>(pi)</em> varies as this: 
843  *              \a bgTuples <= \a pi < \a endTuples.
844  *  \param [in] bgComp - index of the first component of \a this array to assign to.
845  *  \param [in] endComp - index of the component before which the components to assign
846  *              to are located.
847  *  \param [in] stepComp - index increment to get index of the next component to assign to.
848  *  \throw If \a this is not allocated.
849  *  \throw If any index of tuple given by \a bgTuples is out of a valid range for 
850  *         \a this array.
851  *  \throw If parameters specifying components to assign to, do not give a
852  *            non-empty range of increasing indices or indices are out of a valid range
853  *            for \this array.
854  *
855  *  \if ENABLE_EXAMPLES
856  *  \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example".
857  *  \endif
858  */
859 void DataArrayChar::setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp)
860 {
861   const char msg[]="DataArrayChar::setPartOfValuesSimple3";
862   checkAllocated();
863   int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg);
864   int nbComp=getNumberOfComponents();
865   int nbOfTuples=getNumberOfTuples();
866   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
867   char *pt=getPointer()+bgComp;
868   for(const int *w=bgTuples;w!=endTuples;w++)
869     for(int j=0;j<newNbOfComp;j++)
870       {
871         DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id");
872         pt[(*w)*nbComp+j*stepComp]=a;
873       }
874 }
875
876 void DataArrayChar::setPartOfValues4(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare)
877 {
878   if(!a)
879     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
880   const char msg[]="DataArrayInt::setPartOfValues4";
881   checkAllocated();
882   a->checkAllocated();
883   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
884   int newNbOfComp=(int)std::distance(bgComp,endComp);
885   int nbComp=getNumberOfComponents();
886   for(const int *z=bgComp;z!=endComp;z++)
887     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
888   int nbOfTuples=getNumberOfTuples();
889   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
890   bool assignTech=true;
891   if(a->getNbOfElems()==(std::size_t)newNbOfTuples*newNbOfComp)
892     {
893       if(strictCompoCompare)
894         a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
895     }
896   else
897     {
898       a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
899       assignTech=false;
900     }
901   const char *srcPt=a->getConstPointer();
902   char *pt=getPointer()+bgTuples*nbComp;
903   if(assignTech)
904     {
905       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
906         for(const int *z=bgComp;z!=endComp;z++,srcPt++)
907           pt[*z]=*srcPt;
908     }
909   else
910     {
911       for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
912         {
913           const char *srcPt2=srcPt;
914           for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
915             pt[*z]=*srcPt2;
916         }
917     }
918 }
919
920 void DataArrayChar::setPartOfValuesSimple4(char a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp)
921 {
922   const char msg[]="DataArrayInt::setPartOfValuesSimple4";
923   checkAllocated();
924   int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
925   int nbComp=getNumberOfComponents();
926   for(const int *z=bgComp;z!=endComp;z++)
927     DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
928   int nbOfTuples=getNumberOfTuples();
929   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
930   char *pt=getPointer()+bgTuples*nbComp;
931   for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
932     for(const int *z=bgComp;z!=endComp;z++)
933       pt[*z]=a;
934 }
935
936 /*!
937  * Copy some tuples from another DataArrayChar into specified tuples
938  * of \a this array. Textual data is not copied. Both arrays must have equal number of
939  * components.
940  * Both the tuples to assign and the tuples to assign to are defined by a DataArrayChar.
941  * All components of selected tuples are copied.
942  *  \param [in] a - the array to copy values from.
943  *  \param [in] tuplesSelec - the array specifying both source tuples of \a a and
944  *              target tuples of \a this. \a tuplesSelec has two components, and the
945  *              first component specifies index of the source tuple and the second
946  *              one specifies index of the target tuple.
947  *  \throw If \a this is not allocated.
948  *  \throw If \a a is NULL.
949  *  \throw If \a a is not allocated.
950  *  \throw If \a tuplesSelec is NULL.
951  *  \throw If \a tuplesSelec is not allocated.
952  *  \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>.
953  *  \throw If \a tuplesSelec->getNumberOfComponents() != 2.
954  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
955  *         the corresponding (\a this or \a a) array.
956  */
957 void DataArrayChar::setPartOfValuesAdv(const DataArrayChar *a, const DataArrayChar *tuplesSelec)
958 {
959   if(!a || !tuplesSelec)
960     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : DataArrayChar pointer in input is NULL !");
961   checkAllocated();
962   a->checkAllocated();
963   tuplesSelec->checkAllocated();
964   int nbOfComp=getNumberOfComponents();
965   if(nbOfComp!=a->getNumberOfComponents())
966     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : This and a do not have the same number of components !");
967   if(tuplesSelec->getNumberOfComponents()!=2)
968     throw INTERP_KERNEL::Exception("DataArrayChar::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayChar instance with exactly 2 components !");
969   int thisNt=getNumberOfTuples();
970   int aNt=a->getNumberOfTuples();
971   char *valsToSet=getPointer();
972   const char *valsSrc=a->getConstPointer();
973   for(const char *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2)
974     {
975       if(tuple[1]>=0 && tuple[1]<aNt)
976         {
977           if(tuple[0]>=0 && tuple[0]<thisNt)
978             std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]);
979           else
980             {
981               std::ostringstream oss; oss << "DataArrayChar::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
982               oss << " of 'tuplesSelec' request of tuple id #" << tuple[0] << " in 'this' ! It should be in [0," << thisNt << ") !";
983               throw INTERP_KERNEL::Exception(oss.str().c_str());
984             }
985         }
986       else
987         {
988           std::ostringstream oss; oss << "DataArrayChar::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->begin(),tuple)/2;
989           oss << " of 'tuplesSelec' request of tuple id #" << tuple[1] << " in 'a' ! It should be in [0," << aNt << ") !";
990           throw INTERP_KERNEL::Exception(oss.str().c_str());
991         }
992     }
993 }
994
995 /*!
996  * Copy some tuples from another DataArrayChar (\a aBase) into contiguous tuples
997  * of \a this array. Textual data is not copied. Both arrays must have equal number of
998  * components.
999  * The tuples to assign to are defined by index of the first tuple, and
1000  * their number is defined by \a tuplesSelec->getNumberOfTuples().
1001  * The tuples to copy are defined by values of a DataArrayChar.
1002  * All components of selected tuples are copied.
1003  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
1004  *              values to.
1005  *  \param [in] aBase - the array to copy values from.
1006  *  \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy.
1007  *  \throw If \a this is not allocated.
1008  *  \throw If \a aBase is NULL.
1009  *  \throw If \a aBase is not allocated.
1010  *  \throw If \a tuplesSelec is NULL.
1011  *  \throw If \a tuplesSelec is not allocated.
1012  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
1013  *  \throw If \a tuplesSelec->getNumberOfComponents() != 1.
1014  *  \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em>
1015  *  \throw If any tuple index given by \a tuplesSelec is out of a valid range for 
1016  *         \a aBase array.
1017  */
1018 void DataArrayChar::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec)
1019 {
1020   if(!aBase || !tuplesSelec)
1021     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : input DataArray is NULL !");
1022   const DataArrayChar *a=dynamic_cast<const DataArrayChar *>(aBase);
1023   if(!a)
1024     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayChar !");
1025   checkAllocated();
1026   a->checkAllocated();
1027   tuplesSelec->checkAllocated();
1028   int nbOfComp=getNumberOfComponents();
1029   if(nbOfComp!=a->getNumberOfComponents())
1030     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : This and a do not have the same number of components !");
1031   if(tuplesSelec->getNumberOfComponents()!=1)
1032     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayChar instance with exactly 1 component !");
1033   int thisNt=getNumberOfTuples();
1034   int aNt=a->getNumberOfTuples();
1035   int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples();
1036   char *valsToSet=getPointer()+tupleIdStart*nbOfComp;
1037   if(tupleIdStart+nbOfTupleToWrite>thisNt)
1038     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : invalid number range of values to write !");
1039   const char *valsSrc=a->getConstPointer();
1040   for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp)
1041     {
1042       if(*tuple>=0 && *tuple<aNt)
1043         {
1044           std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet);
1045         }
1046       else
1047         {
1048           std::ostringstream oss; oss << "DataArrayChar::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),tuple);
1049           oss << " of 'tuplesSelec' request of tuple id #" << *tuple << " in 'a' ! It should be in [0," << aNt << ") !";
1050           throw INTERP_KERNEL::Exception(oss.str().c_str());
1051         }
1052     }
1053 }
1054
1055 /*!
1056  * Copy some tuples from another DataArrayChar (\a aBase) into contiguous tuples
1057  * of \a this array. Textual data is not copied. Both arrays must have equal number of
1058  * components.
1059  * The tuples to copy are defined by three values similar to parameters of
1060  * the Python function \c range(\c start,\c stop,\c step).
1061  * The tuples to assign to are defined by index of the first tuple, and
1062  * their number is defined by number of tuples to copy.
1063  * All components of selected tuples are copied.
1064  *  \param [in] tupleIdStart - index of the first tuple of \a this array to assign
1065  *              values to.
1066  *  \param [in] aBase - the array to copy values from.
1067  *  \param [in] bg - index of the first tuple to copy of the array \a aBase.
1068  *  \param [in] end2 - index of the tuple of \a aBase before which the tuples to copy
1069  *              are located.
1070  *  \param [in] step - index increment to get index of the next tuple to copy.
1071  *  \throw If \a this is not allocated.
1072  *  \throw If \a aBase is NULL.
1073  *  \throw If \a aBase is not allocated.
1074  *  \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>.
1075  *  \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em>
1076  *  \throw If parameters specifying tuples to copy, do not give a
1077  *            non-empty range of increasing indices or indices are out of a valid range
1078  *            for the array \a aBase.
1079  */
1080 void DataArrayChar::setContigPartOfSelectedValuesSlice(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step)
1081 {
1082   if(!aBase)
1083     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValuesSlice : input DataArray is NULL !");
1084   const DataArrayChar *a=dynamic_cast<const DataArrayChar *>(aBase);
1085   if(!a)
1086     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValuesSlice : input DataArray aBase is not a DataArrayChar !");
1087   checkAllocated();
1088   a->checkAllocated();
1089   int nbOfComp=getNumberOfComponents();
1090   const char msg[]="DataArrayChar::setContigPartOfSelectedValuesSlice";
1091   int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg);
1092   if(nbOfComp!=a->getNumberOfComponents())
1093     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValuesSlice : This and a do not have the same number of components !");
1094   int thisNt=getNumberOfTuples();
1095   int aNt=a->getNumberOfTuples();
1096   char *valsToSet=getPointer()+tupleIdStart*nbOfComp;
1097   if(tupleIdStart+nbOfTupleToWrite>thisNt)
1098     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValuesSlice : invalid number range of values to write !");
1099   if(end2>aNt)
1100     throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValuesSlice : invalid range of values to read !");
1101   const char *valsSrc=a->getConstPointer()+bg*nbOfComp;
1102   for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp)
1103     {
1104       std::copy(valsSrc,valsSrc+nbOfComp,valsToSet);
1105     }
1106 }
1107
1108 /*!
1109  * Returns a shorten copy of \a this array. The new DataArrayChar contains ranges
1110  * of tuples specified by \a ranges parameter.
1111  * For more info on renumbering see \ref numbering.
1112  *  \param [in] ranges - std::vector of std::pair's each of which defines a range
1113  *              of tuples in [\c begin,\c end) format.
1114  *  \return DataArrayChar * - the new instance of DataArrayChar that the caller
1115  *          is to delete using decrRef() as it is no more needed.
1116  *  \throw If \a end < \a begin.
1117  *  \throw If \a end > \a this->getNumberOfTuples().
1118  *  \throw If \a this is not allocated.
1119  */
1120 DataArray *DataArrayChar::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const
1121 {
1122   checkAllocated();
1123   int nbOfComp=getNumberOfComponents();
1124   int nbOfTuplesThis=getNumberOfTuples();
1125   if(ranges.empty())
1126     {
1127       MCAuto<DataArrayChar> ret=buildEmptySpecializedDAChar();
1128       ret->alloc(0,nbOfComp);
1129       ret->copyStringInfoFrom(*this);
1130       return ret.retn();
1131     }
1132   int ref=ranges.front().first;
1133   int nbOfTuples=0;
1134   bool isIncreasing=true;
1135   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1136     {
1137       if((*it).first<=(*it).second)
1138         {
1139           if((*it).first>=0 && (*it).second<=nbOfTuplesThis)
1140             {
1141               nbOfTuples+=(*it).second-(*it).first;
1142               if(isIncreasing)
1143                 isIncreasing=ref<=(*it).first;
1144               ref=(*it).second;
1145             }
1146           else
1147             {
1148               std::ostringstream oss; oss << "DataArrayChar::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1149               oss << " (" << (*it).first << "," << (*it).second << ") is greater than number of tuples of this :" << nbOfTuples << " !";
1150               throw INTERP_KERNEL::Exception(oss.str().c_str());
1151             }
1152         }
1153       else
1154         {
1155           std::ostringstream oss; oss << "DataArrayChar::selectByTupleRanges : on range #" << std::distance(ranges.begin(),it);
1156           oss << " (" << (*it).first << "," << (*it).second << ") end is before begin !";
1157           throw INTERP_KERNEL::Exception(oss.str().c_str());
1158         }
1159     }
1160   if(isIncreasing && nbOfTuplesThis==nbOfTuples)
1161     return deepCopy();
1162   MCAuto<DataArrayChar> ret=buildEmptySpecializedDAChar();
1163   ret->alloc(nbOfTuples,nbOfComp);
1164   ret->copyStringInfoFrom(*this);
1165   const char *src=getConstPointer();
1166   char *work=ret->getPointer();
1167   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
1168     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
1169   return ret.retn();
1170 }
1171
1172 /*!
1173  * Returns the first value of \a this. 
1174  *  \return char - the last value of \a this array.
1175  *  \throw If \a this is not allocated.
1176  *  \throw If \a this->getNumberOfComponents() != 1.
1177  *  \throw If \a this->getNumberOfTuples() < 1.
1178  */
1179 char DataArrayChar::front() const
1180 {
1181   checkAllocated();
1182   if(getNumberOfComponents()!=1)
1183     throw INTERP_KERNEL::Exception("DataArrayChar::front : number of components not equal to one !");
1184   int nbOfTuples=getNumberOfTuples();
1185   if(nbOfTuples<1)
1186     throw INTERP_KERNEL::Exception("DataArrayChar::front : number of tuples must be >= 1 !");
1187   return *(getConstPointer());
1188 }
1189
1190 /*!
1191  * Returns the last value of \a this. 
1192  *  \return char - the last value of \a this array.
1193  *  \throw If \a this is not allocated.
1194  *  \throw If \a this->getNumberOfComponents() != 1.
1195  *  \throw If \a this->getNumberOfTuples() < 1.
1196  */
1197 char DataArrayChar::back() const
1198 {
1199   checkAllocated();
1200   if(getNumberOfComponents()!=1)
1201     throw INTERP_KERNEL::Exception("DataArrayChar::back : number of components not equal to one !");
1202   int nbOfTuples=getNumberOfTuples();
1203   if(nbOfTuples<1)
1204     throw INTERP_KERNEL::Exception("DataArrayChar::back : number of tuples must be >= 1 !");
1205   return *(getConstPointer()+nbOfTuples-1);
1206 }
1207
1208 /*!
1209  * Creates a new DataArrayChar containing IDs (indices) of tuples holding value equal to a
1210  * given one.
1211  *  \param [in] val - the value to find within \a this.
1212  *  \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this
1213  *          array using decrRef() as it is no more needed.
1214  *  \throw If \a this is not allocated.
1215  *  \throw If \a this->getNumberOfComponents() != 1.
1216  */
1217 DataArrayInt *DataArrayChar::findIdsEqual(char val) const
1218 {
1219   checkAllocated();
1220   if(getNumberOfComponents()!=1)
1221     throw INTERP_KERNEL::Exception("DataArrayChar::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
1222   const char *cptr=getConstPointer();
1223   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1224   int nbOfTuples=getNumberOfTuples();
1225   for(int i=0;i<nbOfTuples;i++,cptr++)
1226     if(*cptr==val)
1227       ret->pushBackSilent(i);
1228   return ret.retn();
1229 }
1230
1231 /*!
1232  * Creates a new DataArrayChar containing IDs (indices) of tuples holding value \b not
1233  * equal to a given one. 
1234  *  \param [in] val - the value to ignore within \a this.
1235  *  \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this
1236  *          array using decrRef() as it is no more needed.
1237  *  \throw If \a this is not allocated.
1238  *  \throw If \a this->getNumberOfComponents() != 1.
1239  */
1240 DataArrayInt *DataArrayChar::findIdsNotEqual(char val) const
1241 {
1242   checkAllocated();
1243   if(getNumberOfComponents()!=1)
1244     throw INTERP_KERNEL::Exception("DataArrayChar::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
1245   const char *cptr=getConstPointer();
1246   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
1247   int nbOfTuples=getNumberOfTuples();
1248   for(int i=0;i<nbOfTuples;i++,cptr++)
1249     if(*cptr!=val)
1250       ret->pushBackSilent(i);
1251   return ret.retn();
1252 }
1253
1254 /*!
1255  * This method searches the sequence specified in input parameter \b vals in \b this.
1256  * This works only for DataArrayChar having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
1257  * This method differs from DataArrayChar::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayChar::findIdFirstEqualTuple.
1258  * \sa DataArrayChar::findIdFirstEqualTuple
1259  */
1260 int DataArrayChar::findIdSequence(const std::vector<char>& vals) const
1261 {
1262   checkAllocated();
1263   int nbOfCompo=getNumberOfComponents();
1264   if(nbOfCompo!=1)
1265     throw INTERP_KERNEL::Exception("DataArrayChar::findIdSequence : works only for DataArrayChar instance with one component !");
1266   const char *cptr=getConstPointer();
1267   std::size_t nbOfVals=getNbOfElems();
1268   const char *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
1269   if(loc!=cptr+nbOfVals)
1270     return std::distance(cptr,loc);
1271   return -1;
1272 }
1273
1274 /*!
1275  * This method is an extension of DataArrayChar::findIdFirstEqual method because this method works for DataArrayChar with
1276  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
1277  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
1278  * If any the tuple id is returned. If not -1 is returned.
1279  * 
1280  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
1281  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
1282  *
1283  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
1284  * \sa DataArrayChar::findIdSequence.
1285  */
1286 int DataArrayChar::findIdFirstEqualTuple(const std::vector<char>& tupl) const
1287 {
1288   checkAllocated();
1289   int nbOfCompo=getNumberOfComponents();
1290   if(nbOfCompo==0)
1291     throw INTERP_KERNEL::Exception("DataArrayChar::findIdFirstEqualTuple : 0 components in 'this' !");
1292   if(nbOfCompo!=(int)tupl.size())
1293     {
1294       std::ostringstream oss; oss << "DataArrayChar::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
1295       throw INTERP_KERNEL::Exception(oss.str().c_str());
1296     }
1297   const char *cptr=getConstPointer();
1298   std::size_t nbOfVals=getNbOfElems();
1299   for(const char *work=cptr;work!=cptr+nbOfVals;)
1300     {
1301       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
1302       if(work!=cptr+nbOfVals)
1303         {
1304           if(std::distance(cptr,work)%nbOfCompo!=0)
1305             work++;
1306           else
1307             return std::distance(cptr,work)/nbOfCompo;
1308         }
1309     }
1310   return -1;
1311 }
1312
1313 /*!
1314  * This method is an extension of DataArrayChar::presenceOfValue method because this method works for DataArrayChar with
1315  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
1316  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
1317  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
1318  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
1319  * \sa DataArrayChar::findIdFirstEqualTuple
1320  */
1321 bool DataArrayChar::presenceOfTuple(const std::vector<char>& tupl) const
1322 {
1323   return findIdFirstEqualTuple(tupl)!=-1;
1324 }
1325
1326 /*!
1327  * Returns \a true if a given value is present within \a this one-dimensional array.
1328  *  \param [in] value - the value to find within \a this array.
1329  *  \return bool - \a true in case if \a value is present within \a this array.
1330  *  \throw If \a this is not allocated.
1331  *  \throw If \a this->getNumberOfComponents() != 1.
1332  *  \sa findIdFirstEqual()
1333  */
1334 bool DataArrayChar::presenceOfValue(char value) const
1335 {
1336   return findIdFirstEqual(value)!=-1;
1337 }
1338
1339 /*!
1340  * This method expects to be called when number of components of this is equal to one.
1341  * This method returns true if it exists a tuple so that the value is contained in \b vals.
1342  * If not any tuple contains one of the values contained in 'vals' false is returned.
1343  * \sa DataArrayChar::findIdFirstEqual
1344  */
1345 bool DataArrayChar::presenceOfValue(const std::vector<char>& vals) const
1346 {
1347   return findIdFirstEqual(vals)!=-1;
1348 }
1349
1350 /*!
1351  * This method expects to be called when number of components of this is equal to one.
1352  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
1353  * If not any tuple contains \b value -1 is returned.
1354  * \sa DataArrayChar::presenceOfValue
1355  */
1356 int DataArrayChar::findIdFirstEqual(char value) const
1357 {
1358   checkAllocated();
1359   if(getNumberOfComponents()!=1)
1360     throw INTERP_KERNEL::Exception("DataArrayChar::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
1361   const char *cptr=getConstPointer();
1362   int nbOfTuples=getNumberOfTuples();
1363   const char *ret=std::find(cptr,cptr+nbOfTuples,value);
1364   if(ret!=cptr+nbOfTuples)
1365     return std::distance(cptr,ret);
1366   return -1;
1367 }
1368
1369 /*!
1370  * This method expects to be called when number of components of this is equal to one.
1371  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
1372  * If not any tuple contains one of the values contained in 'vals' false is returned.
1373  * \sa DataArrayChar::presenceOfValue
1374  */
1375 int DataArrayChar::findIdFirstEqual(const std::vector<char>& vals) const
1376 {
1377   checkAllocated();
1378   if(getNumberOfComponents()!=1)
1379     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
1380   std::set<char> vals2(vals.begin(),vals.end());
1381   const char *cptr=getConstPointer();
1382   int nbOfTuples=getNumberOfTuples();
1383   for(const char *w=cptr;w!=cptr+nbOfTuples;w++)
1384     if(vals2.find(*w)!=vals2.end())
1385       return std::distance(cptr,w);
1386   return -1;
1387 }
1388
1389 /*!
1390  * Returns the maximal value and its location within \a this one-dimensional array.
1391  *  \param [out] tupleId - index of the tuple holding the maximal value.
1392  *  \return char - the maximal value among all values of \a this array.
1393  *  \throw If \a this->getNumberOfComponents() != 1
1394  *  \throw If \a this->getNumberOfTuples() < 1
1395  */
1396 char DataArrayChar::getMaxValue(int& tupleId) const
1397 {
1398   checkAllocated();
1399   if(getNumberOfComponents()!=1)
1400     throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : must be applied on DataArrayChar with only one component !");
1401   int nbOfTuples=getNumberOfTuples();
1402   if(nbOfTuples<=0)
1403     throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : array exists but number of tuples must be > 0 !");
1404   const char *vals=getConstPointer();
1405   const char *loc=std::max_element(vals,vals+nbOfTuples);
1406   tupleId=(int)std::distance(vals,loc);
1407   return *loc;
1408 }
1409
1410 /*!
1411  * Returns the maximal value within \a this array that is allowed to have more than
1412  *  one component.
1413  *  \return char - the maximal value among all values of \a this array.
1414  *  \throw If \a this is not allocated.
1415  */
1416 char DataArrayChar::getMaxValueInArray() const
1417 {
1418   checkAllocated();
1419   const char *loc=std::max_element(begin(),end());
1420   return *loc;
1421 }
1422
1423 /*!
1424  * Returns the minimal value and its location within \a this one-dimensional array.
1425  *  \param [out] tupleId - index of the tuple holding the minimal value.
1426  *  \return char - the minimal value among all values of \a this array.
1427  *  \throw If \a this->getNumberOfComponents() != 1
1428  *  \throw If \a this->getNumberOfTuples() < 1
1429  */
1430 char DataArrayChar::getMinValue(int& tupleId) const
1431 {
1432   checkAllocated();
1433   if(getNumberOfComponents()!=1)
1434     throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : must be applied on DataArrayChar with only one component !");
1435   int nbOfTuples=getNumberOfTuples();
1436   if(nbOfTuples<=0)
1437     throw INTERP_KERNEL::Exception("DataArrayChar::getMaxValue : array exists but number of tuples must be > 0 !");
1438   const char *vals=getConstPointer();
1439   const char *loc=std::min_element(vals,vals+nbOfTuples);
1440   tupleId=(int)std::distance(vals,loc);
1441   return *loc;
1442 }
1443
1444 /*!
1445  * Returns the minimal value within \a this array that is allowed to have more than
1446  *  one component.
1447  *  \return char - the minimal value among all values of \a this array.
1448  *  \throw If \a this is not allocated.
1449  */
1450 char DataArrayChar::getMinValueInArray() const
1451 {
1452   checkAllocated();
1453   const char *loc=std::min_element(begin(),end());
1454   return *loc;
1455 }
1456
1457 /*!
1458  * This method works only on data array with one component.
1459  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
1460  * this[*id] in [\b vmin,\b vmax)
1461  * 
1462  * \param [in] vmin begin of range. This value is included in range.
1463  * \param [in] vmax end of range. This value is \b not included in range.
1464  * \return a newly allocated data array that the caller should deal with.
1465  */
1466 DataArrayInt *DataArrayChar::findIdsInRange(char vmin, char vmax) const
1467 {
1468   checkAllocated();
1469   if(getNumberOfComponents()!=1)
1470     throw INTERP_KERNEL::Exception("DataArrayChar::findIdsInRange : this must have exactly one component !");
1471   const char *cptr=getConstPointer();
1472   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
1473   int nbOfTuples=getNumberOfTuples();
1474   for(int i=0;i<nbOfTuples;i++,cptr++)
1475     if(*cptr>=vmin && *cptr<vmax)
1476       ret->pushBackSilent(i);
1477   return ret.retn();
1478 }
1479
1480 /*!
1481  * Returns a new DataArrayChar by concatenating two given arrays, so that (1) the number
1482  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
1483  * offsetA2</em> and (2)
1484  * the number of component in the result array is same as that of each of given arrays.
1485  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
1486  * Info on components is copied from the first of the given arrays. Number of components
1487  * in the given arrays must be the same.
1488  *  \param [in] a1 - an array to include in the result array.
1489  *  \param [in] a2 - another array to include in the result array.
1490  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
1491  *  \return DataArrayChar * - the new instance of DataArrayChar.
1492  *          The caller is to delete this result array using decrRef() as it is no more
1493  *          needed.
1494  *  \throw If either \a a1 or \a a2 is NULL.
1495  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
1496  */
1497 DataArrayChar *DataArrayChar::Aggregate(const DataArrayChar *a1, const DataArrayChar *a2)
1498 {
1499   if(!a1 || !a2)
1500     throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input DataArrayChar instance is NULL !");
1501   std::vector<const DataArrayChar *> v(2); v[0]=a1; v[1]=a2;
1502   return Aggregate(v);
1503 }
1504
1505 /*!
1506  * Returns a new DataArrayChar by concatenating all given arrays, so that (1) the number
1507  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
1508  * the number of component in the result array is same as that of each of given arrays.
1509  * Info on components is copied from the first of the given arrays. Number of components
1510  * in the given arrays must be  the same.
1511  *  \param [in] arr - a sequence of arrays to include in the result array.
1512  *  \return DataArrayChar * - the new instance of DataArrayChar.
1513  *          The caller is to delete this result array using decrRef() as it is no more
1514  *          needed.
1515  *  \throw If all arrays within \a arr are NULL.
1516  *  \throw If getNumberOfComponents() of arrays within \a arr.
1517  */
1518 DataArrayChar *DataArrayChar::Aggregate(const std::vector<const DataArrayChar *>& arr)
1519 {
1520   std::vector<const DataArrayChar *> a;
1521   for(std::vector<const DataArrayChar *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
1522     if(*it4)
1523       a.push_back(*it4);
1524   if(a.empty())
1525     throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input list must be NON EMPTY !");
1526   std::vector<const DataArrayChar *>::const_iterator it=a.begin();
1527   int nbOfComp=(*it)->getNumberOfComponents();
1528   int nbt=(*it++)->getNumberOfTuples();
1529   for(int i=1;it!=a.end();it++,i++)
1530     {
1531       if((*it)->getNumberOfComponents()!=nbOfComp)
1532         throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : Nb of components mismatch for array aggregation !");
1533       nbt+=(*it)->getNumberOfTuples();
1534     }
1535   MCAuto<DataArrayChar> ret=a[0]->buildEmptySpecializedDAChar();
1536   ret->alloc(nbt,nbOfComp);
1537   char *pt=ret->getPointer();
1538   for(it=a.begin();it!=a.end();it++)
1539     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
1540   ret->copyStringInfoFrom(*(a[0]));
1541   return ret.retn();
1542 }
1543
1544 /*!
1545  * Returns a new DataArrayChar by aggregating two given arrays, so that (1) the number
1546  * of components in the result array is a sum of the number of components of given arrays
1547  * and (2) the number of tuples in the result array is same as that of each of given
1548  * arrays. In other words the i-th tuple of result array includes all components of
1549  * i-th tuples of all given arrays.
1550  * Number of tuples in the given arrays must be the same.
1551  *  \param [in] a1 - an array to include in the result array.
1552  *  \param [in] a2 - another array to include in the result array.
1553  *  \return DataArrayChar * - the new instance of DataArrayChar.
1554  *          The caller is to delete this result array using decrRef() as it is no more
1555  *          needed.
1556  *  \throw If both \a a1 and \a a2 are NULL.
1557  *  \throw If any given array is not allocated.
1558  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
1559  */
1560 DataArrayChar *DataArrayChar::Meld(const DataArrayChar *a1, const DataArrayChar *a2)
1561 {
1562   std::vector<const DataArrayChar *> arr(2);
1563   arr[0]=a1; arr[1]=a2;
1564   return Meld(arr);
1565 }
1566
1567 /*!
1568  * Returns a new DataArrayChar by aggregating all given arrays, so that (1) the number
1569  * of components in the result array is a sum of the number of components of given arrays
1570  * and (2) the number of tuples in the result array is same as that of each of given
1571  * arrays. In other words the i-th tuple of result array includes all components of
1572  * i-th tuples of all given arrays.
1573  * Number of tuples in the given arrays must be  the same.
1574  *  \param [in] arr - a sequence of arrays to include in the result array.
1575  *  \return DataArrayChar * - the new instance of DataArrayChar.
1576  *          The caller is to delete this result array using decrRef() as it is no more
1577  *          needed.
1578  *  \throw If all arrays within \a arr are NULL.
1579  *  \throw If any given array is not allocated.
1580  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
1581  */
1582 DataArrayChar *DataArrayChar::Meld(const std::vector<const DataArrayChar *>& arr)
1583 {
1584   std::vector<const DataArrayChar *> a;
1585   for(std::vector<const DataArrayChar *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
1586     if(*it4)
1587       a.push_back(*it4);
1588   if(a.empty())
1589     throw INTERP_KERNEL::Exception("DataArrayChar::Meld : array must be NON empty !");
1590   std::vector<const DataArrayChar *>::const_iterator it;
1591   for(it=a.begin();it!=a.end();it++)
1592     (*it)->checkAllocated();
1593   it=a.begin();
1594   int nbOfTuples=(*it)->getNumberOfTuples();
1595   std::vector<int> nbc(a.size());
1596   std::vector<const char *> pts(a.size());
1597   nbc[0]=(*it)->getNumberOfComponents();
1598   pts[0]=(*it++)->getConstPointer();
1599   for(int i=1;it!=a.end();it++,i++)
1600     {
1601       if(nbOfTuples!=(*it)->getNumberOfTuples())
1602         throw INTERP_KERNEL::Exception("DataArrayChar::meld : mismatch of number of tuples !");
1603       nbc[i]=(*it)->getNumberOfComponents();
1604       pts[i]=(*it)->getConstPointer();
1605     }
1606   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
1607   DataArrayChar *ret=a[0]->buildEmptySpecializedDAChar();
1608   ret->alloc(nbOfTuples,totalNbOfComp);
1609   char *retPtr=ret->getPointer();
1610   for(int i=0;i<nbOfTuples;i++)
1611     for(int j=0;j<(int)a.size();j++)
1612       {
1613         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
1614         pts[j]+=nbc[j];
1615       }
1616   int k=0;
1617   for(int i=0;i<(int)a.size();i++)
1618     for(int j=0;j<nbc[i];j++,k++)
1619       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
1620   return ret;
1621 }
1622
1623 /*!
1624  * Returns a new instance of DataArrayByte. The caller is to delete this array
1625  * using decrRef() as it is no more needed. 
1626  */
1627 DataArrayByte *DataArrayByte::New()
1628 {
1629   return new DataArrayByte;
1630 }
1631
1632 DataArrayByteIterator *DataArrayByte::iterator()
1633 {
1634   return new DataArrayByteIterator(this);
1635 }
1636
1637 /*!
1638  * Returns a full copy of \a this. For more info on copying data arrays see
1639  * \ref MEDCouplingArrayBasicsCopyDeep.
1640  *  \return DataArrayByte * - a new instance of DataArrayByte.
1641  */
1642 DataArrayByte *DataArrayByte::deepCopy() const
1643 {
1644   return new DataArrayByte(*this);
1645 }
1646
1647 /*!
1648  * Returns either a \a deep or \a shallow copy of this array. For more info see
1649  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
1650  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
1651  *  \return DataArrayByte * - either a new instance of DataArrayByte (if \a dCpy
1652  *          == \a true) or \a this instance (if \a dCpy == \a false).
1653  */
1654 DataArrayByte *DataArrayByte::performCopyOrIncrRef(bool dCpy) const
1655 {
1656   if(dCpy)
1657     return deepCopy();
1658   else
1659     {
1660       incrRef();
1661       return const_cast<DataArrayByte *>(this);
1662     }
1663 }
1664
1665 /*!
1666  * Returns the only one value in \a this, if and only if number of elements
1667  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
1668  *  \return char - the sole value stored in \a this array.
1669  *  \throw If at least one of conditions stated above is not fulfilled.
1670  */
1671 char DataArrayByte::byteValue() const
1672 {
1673   if(isAllocated())
1674     {
1675       if(getNbOfElems()==1)
1676         {
1677           return *getConstPointer();
1678         }
1679       else
1680         throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is allocated but number of elements is not equal to 1 !");
1681     }
1682   else
1683     throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is not allocated !");
1684 }
1685
1686 DataArrayChar *DataArrayByte::buildEmptySpecializedDAChar() const
1687 {
1688   return DataArrayByte::New();
1689 }
1690
1691 void DataArrayByte::reprStream(std::ostream& stream) const
1692 {
1693   stream << "Name of byte array : \"" << _name << "\"\n";
1694   reprWithoutNameStream(stream);
1695 }
1696
1697 void DataArrayByte::reprZipStream(std::ostream& stream) const
1698 {
1699   stream << "Name of byte array : \"" << _name << "\"\n";
1700   reprZipWithoutNameStream(stream);
1701 }
1702
1703 void DataArrayByte::reprWithoutNameStream(std::ostream& stream) const
1704 {
1705   DataArray::reprWithoutNameStream(stream);
1706   if(_mem.reprHeader(getNumberOfComponents(),stream))
1707     {
1708       const char *data=begin();
1709       int nbOfTuples=getNumberOfTuples();
1710       int nbCompo=getNumberOfComponents();
1711       for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
1712         {
1713           stream << "Tuple #" << i << " : ";
1714           std::copy(data,data+nbCompo,std::ostream_iterator<int>(stream," "));//it is not a bug int here not char because it is not ASCII here contrary to DataArrayAsciiChar
1715           stream << "\n";
1716         }
1717     }
1718 }
1719
1720 void DataArrayByte::reprZipWithoutNameStream(std::ostream& stream) const
1721 {
1722   DataArray::reprWithoutNameStream(stream);
1723   _mem.reprZip(getNumberOfComponents(),stream);
1724 }
1725
1726 void DataArrayByte::reprCppStream(const std::string& varName, std::ostream& stream) const
1727 {
1728   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1729   const char *data=getConstPointer();
1730   stream << "DataArrayByte *" << varName << "=DataArrayByte::New();" << std::endl;
1731   if(nbTuples*nbComp>=1)
1732     {
1733       stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={";
1734       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<char>(stream,","));
1735       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1736       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1737     }
1738   else
1739     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1740   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1741 }
1742
1743 /*!
1744  * Method that gives a quick overvien of \a this for python.
1745  */
1746 void DataArrayByte::reprQuickOverview(std::ostream& stream) const
1747 {
1748   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1749   stream << "DataArrayByte C++ instance at " << this << ". ";
1750   if(isAllocated())
1751     {
1752       int nbOfCompo=(int)_info_on_compo.size();
1753       if(nbOfCompo>=1)
1754         {
1755           int nbOfTuples=getNumberOfTuples();
1756           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1757           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1758         }
1759       else
1760         stream << "Number of components : 0.";
1761     }
1762   else
1763     stream << "*** No data allocated ****";
1764 }
1765
1766 void DataArrayByte::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1767 {
1768   const char *data=begin();
1769   int nbOfTuples=getNumberOfTuples();
1770   int nbOfCompo=(int)_info_on_compo.size();
1771   std::ostringstream oss2; oss2 << "[";
1772   std::string oss2Str(oss2.str());
1773   bool isFinished=true;
1774   for(int i=0;i<nbOfTuples && isFinished;i++)
1775     {
1776       if(nbOfCompo>1)
1777         {
1778           oss2 << "(";
1779           for(int j=0;j<nbOfCompo;j++,data++)
1780             {
1781               oss2 << (int)*data;
1782               if(j!=nbOfCompo-1) oss2 << ", ";
1783             }
1784           oss2 << ")";
1785         }
1786       else
1787         { oss2 << (int)*data; data++; }
1788       if(i!=nbOfTuples-1) oss2 << ", ";
1789       std::string oss3Str(oss2.str());
1790       if(oss3Str.length()<maxNbOfByteInRepr)
1791         oss2Str=oss3Str;
1792       else
1793         isFinished=false;
1794     }
1795   stream << oss2Str;
1796   if(!isFinished)
1797     stream << "... ";
1798   stream << "]";
1799 }
1800
1801 bool DataArrayByte::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
1802 {
1803   const DataArrayByte *otherC=dynamic_cast<const DataArrayByte *>(&other);
1804   if(!otherC)
1805     { reason="this is of type DataArrayByte whereas other is not a DataArrayByte instance"; return false; }
1806   return DataArrayChar::isEqualIfNotWhy(other,reason);
1807 }
1808
1809 /*!
1810  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
1811  * \throw if \a this is not allocated.
1812  * \throw if \a this has not exactly one component.
1813  */
1814 std::vector<bool> DataArrayByte::toVectorOfBool() const
1815 {
1816   checkAllocated();
1817   if(getNumberOfComponents()!=1)
1818     throw INTERP_KERNEL::Exception("DataArrayByte::toVectorOfBool : this method can be used only if this has one component !");
1819   int nbt(getNumberOfTuples());
1820   std::vector<bool> ret(nbt,false);
1821   const char *pt(begin());
1822   for(int i=0;i<nbt;i++,pt++)
1823     if(*pt!=0)
1824       ret[i]=true;
1825   return ret;
1826 }
1827
1828 DataArrayByteIterator::DataArrayByteIterator(DataArrayByte *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
1829 {
1830   if(_da)
1831     {
1832       _da->incrRef();
1833       if(_da->isAllocated())
1834         {
1835           _nb_comp=da->getNumberOfComponents();
1836           _nb_tuple=da->getNumberOfTuples();
1837           _pt=da->getPointer();
1838         }
1839     }
1840 }
1841
1842 DataArrayByteIterator::~DataArrayByteIterator()
1843 {
1844   if(_da)
1845     _da->decrRef();
1846 }
1847
1848 DataArrayByteTuple *DataArrayByteIterator::nextt()
1849 {
1850   if(_tuple_id<_nb_tuple)
1851     {
1852       _tuple_id++;
1853       DataArrayByteTuple *ret=new DataArrayByteTuple(_pt,_nb_comp);
1854       _pt+=_nb_comp;
1855       return ret;
1856     }
1857   else
1858     return 0;
1859 }
1860
1861 DataArrayByteTuple::DataArrayByteTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
1862 {
1863 }
1864
1865 std::string DataArrayByteTuple::repr() const
1866 {
1867   std::ostringstream oss; oss << "(";
1868   for(int i=0;i<_nb_of_compo-1;i++)
1869     oss << (int)_pt[i] << ", ";
1870   oss << _pt[_nb_of_compo-1] << ")";
1871   return oss.str();
1872 }
1873
1874 char DataArrayByteTuple::byteValue() const
1875 {
1876   if(_nb_of_compo==1)
1877     return *_pt;
1878   throw INTERP_KERNEL::Exception("DataArrayByteTuple::byteValue : DataArrayByteTuple instance has not exactly 1 component -> Not possible to convert it into an character !");
1879 }
1880
1881 /*!
1882  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayByte::decrRef.
1883  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayByte::useArray with ownership set to \b false.
1884  * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or
1885  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
1886  */
1887 DataArrayByte *DataArrayByteTuple::buildDAByte(int nbOfTuples, int nbOfCompo) const
1888 {
1889   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
1890     {
1891       DataArrayByte *ret=DataArrayByte::New();
1892       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
1893       return ret;
1894     }
1895   else
1896     {
1897       std::ostringstream oss; oss << "DataArrayByteTuple::buildDAByte : unable to build a requested DataArrayByte instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
1898       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
1899       throw INTERP_KERNEL::Exception(oss.str().c_str());
1900     }
1901 }
1902
1903 /*!
1904  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
1905  * using decrRef() as it is no more needed. 
1906  */
1907 DataArrayAsciiChar *DataArrayAsciiChar::New()
1908 {
1909   return new DataArrayAsciiChar;
1910 }
1911
1912 /*!
1913  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
1914  * using decrRef() as it is no more needed. 
1915  * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown.
1916  */
1917 DataArrayAsciiChar *DataArrayAsciiChar::New(const std::string& st)
1918 {
1919   return new DataArrayAsciiChar(st);
1920 }
1921
1922 /*!
1923  * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown.
1924  */
1925 DataArrayAsciiChar::DataArrayAsciiChar(const std::string& st)
1926 {
1927   std::size_t lgth=st.length();
1928   if(lgth==0)
1929     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with string ! Size of input string is null !");
1930   alloc(1,lgth);
1931   std::copy(st.begin(),st.begin()+lgth,getPointer());
1932 }
1933
1934 /*!
1935  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
1936  * using decrRef() as it is no more needed. 
1937  * This constructor uses \a vst input vector of strings to initialize itself. For all strings whose length is lower than max length of strings in
1938  * \a vst the remaining locations in memory will be set to character \a defaultChar.
1939  *
1940  * \param [in] defaultChar the default character used to fill not defined locations in \a this
1941  * \param [in] vst vector of strings. This input vector must be non empty. \a this will have its component size set to the max lgth of strings contained
1942  *             in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown.
1943  *
1944  * \throw If input \a vst is empty.
1945  * \throw If all strings in \a vst are empty.
1946  */
1947 DataArrayAsciiChar *DataArrayAsciiChar::New(const std::vector<std::string>& vst, char defaultChar)
1948 {
1949   return new DataArrayAsciiChar(vst,defaultChar);
1950 }
1951
1952 /*!
1953  * This constructor uses \a vst input vector of strings to initialize itself. For all strings whose length is lower than max length of strings in
1954  * \a vst the remaining locations in memory will be set to character \a defaultChar.
1955  *
1956  * \param [in] defaultChar the default character used to fill not defined locations in \a this
1957  * \param [in] vst vector of strings. This input vector must be non empty. \a this will have its component size set to the max lgth of strings contained
1958  *             in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown.
1959  *
1960  * \throw If input \a vst is empty.
1961  * \throw If all strings in \a vst are empty.
1962  */
1963 DataArrayAsciiChar::DataArrayAsciiChar(const std::vector<std::string>& vst, char defaultChar)
1964 {
1965   if(vst.empty())
1966     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! Empty array !");
1967   std::size_t nbCompo=0;
1968   for(std::vector<std::string>::const_iterator it=vst.begin();it!=vst.end();it++)
1969     nbCompo=std::max(nbCompo,(*it).length());
1970   if(nbCompo==0)
1971     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! All strings in not empty vector are empty !");
1972   int nbTuples=(int)vst.size();
1973   alloc(nbTuples,(int)nbCompo);
1974   char *pt=getPointer();
1975   for(int i=0;i<nbTuples;i++,pt+=nbCompo)
1976     {
1977       const std::string& tmp=vst[i];
1978       std::size_t sz=tmp.length();
1979       std::copy(tmp.begin(),tmp.begin()+sz,pt);
1980       std::fill(pt+sz,pt+nbCompo,defaultChar);
1981     }
1982 }
1983
1984 DataArrayAsciiCharIterator *DataArrayAsciiChar::iterator()
1985 {
1986   return new DataArrayAsciiCharIterator(this);
1987 }
1988
1989 /*!
1990  * Returns a full copy of \a this. For more info on copying data arrays see
1991  * \ref MEDCouplingArrayBasicsCopyDeep.
1992  *  \return DataArrayAsciiChar * - a new instance of DataArrayAsciiChar.
1993  */
1994 DataArrayAsciiChar *DataArrayAsciiChar::deepCopy() const
1995 {
1996   return new DataArrayAsciiChar(*this);
1997 }
1998
1999 /*!
2000  * Returns either a \a deep or \a shallow copy of this array. For more info see
2001  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
2002  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
2003  *  \return DataArrayAsciiChar * - either a new instance of DataArrayAsciiChar (if \a dCpy
2004  *          == \a true) or \a this instance (if \a dCpy == \a false).
2005  */
2006 DataArrayAsciiChar *DataArrayAsciiChar::performCopyOrIncrRef(bool dCpy) const
2007 {
2008   if(dCpy)
2009     return deepCopy();
2010   else
2011     {
2012       incrRef();
2013       return const_cast<DataArrayAsciiChar *>(this);
2014     }
2015 }
2016
2017 /*!
2018  * Returns the only one value in \a this, if and only if number of elements
2019  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
2020  *  \return char - the sole value stored in \a this array.
2021  *  \throw If at least one of conditions stated above is not fulfilled.
2022  */
2023 char DataArrayAsciiChar::asciiCharValue() const
2024 {
2025   if(isAllocated())
2026     {
2027       if(getNbOfElems()==1)
2028         {
2029           return *getConstPointer();
2030         }
2031       else
2032         throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is allocated but number of elements is not equal to 1 !");
2033     }
2034   else
2035     throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is not allocated !");
2036 }
2037
2038 DataArrayChar *DataArrayAsciiChar::buildEmptySpecializedDAChar() const
2039 {
2040   return DataArrayAsciiChar::New();
2041 }
2042
2043 void DataArrayAsciiChar::reprStream(std::ostream& stream) const
2044 {
2045   stream << "Name of ASCII char array : \"" << _name << "\"\n";
2046   reprWithoutNameStream(stream);
2047 }
2048
2049 void DataArrayAsciiChar::reprZipStream(std::ostream& stream) const
2050 {
2051   stream << "Name of ASCII char array : \"" << _name << "\"\n";
2052   reprZipWithoutNameStream(stream);
2053 }
2054
2055 void DataArrayAsciiChar::reprWithoutNameStream(std::ostream& stream) const
2056 {
2057   DataArray::reprWithoutNameStream(stream);
2058   if(_mem.reprHeader(getNumberOfComponents(),stream))
2059     {
2060       const char *data=begin();
2061       int nbOfTuples=getNumberOfTuples();
2062       int nbCompo=getNumberOfComponents();
2063       for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
2064         {
2065           stream << "Tuple #" << i << " : \"";
2066           std::copy(data,data+nbCompo,std::ostream_iterator<char>(stream));
2067           stream << "\"\n";
2068         }
2069     }
2070 }
2071
2072 void DataArrayAsciiChar::reprZipWithoutNameStream(std::ostream& stream) const
2073 {
2074   reprWithoutNameStream(stream);
2075 }
2076
2077 void DataArrayAsciiChar::reprCppStream(const std::string& varName, std::ostream& stream) const
2078 {
2079   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
2080   const char *data=getConstPointer();
2081   stream << "DataArrayAsciiChar *" << varName << "=DataArrayAsciiChar::New();" << std::endl;
2082   if(nbTuples*nbComp>=1)
2083     {
2084       stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={";
2085       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<char>(stream,","));
2086       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
2087       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
2088     }
2089   else
2090     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
2091   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
2092 }
2093
2094 /*!
2095  * Method that gives a quick overvien of \a this for python.
2096  */
2097 void DataArrayAsciiChar::reprQuickOverview(std::ostream& stream) const
2098 {
2099   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
2100   stream << "DataArrayAsciiChar C++ instance at " << this << ". ";
2101   if(isAllocated())
2102     {
2103       int nbOfCompo=(int)_info_on_compo.size();
2104       if(nbOfCompo>=1)
2105         {
2106           int nbOfTuples=getNumberOfTuples();
2107           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
2108           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
2109         }
2110       else
2111         stream << "Number of components : 0.";
2112     }
2113   else
2114     stream << "*** No data allocated ****";
2115 }
2116
2117 void DataArrayAsciiChar::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
2118 {
2119   const char *data=begin();
2120   int nbOfTuples=getNumberOfTuples();
2121   int nbOfCompo=(int)_info_on_compo.size();
2122   std::ostringstream oss2; oss2 << "[";
2123   std::string oss2Str(oss2.str());
2124   bool isFinished=true;
2125   for(int i=0;i<nbOfTuples && isFinished;i++)
2126     {
2127       bool isAscii=true;
2128       for(int j=0;j<nbOfCompo;j++)
2129         if(data[j]<32) isAscii=false;
2130       if(isAscii)
2131         {
2132           oss2 << "\'";
2133           for(int j=0;j<nbOfCompo;j++,data++)
2134             oss2 << *data;
2135           oss2 << "\'";
2136         }
2137       else
2138         {
2139           oss2 << "(";
2140           for(int j=0;j<nbOfCompo;j++,data++)
2141             {
2142               oss2 << (int)*data;
2143               if(j!=nbOfCompo-1) oss2 << ", ";
2144             }
2145           oss2 << ")";
2146         }
2147       if(i!=nbOfTuples-1) oss2 << ", ";
2148       std::string oss3Str(oss2.str());
2149       if(oss3Str.length()<maxNbOfByteInRepr)
2150         oss2Str=oss3Str;
2151       else
2152         isFinished=false;
2153     }
2154   stream << oss2Str;
2155   if(!isFinished)
2156     stream << "... ";
2157   stream << "]";
2158 }
2159
2160 bool DataArrayAsciiChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
2161 {
2162   const DataArrayAsciiChar *otherC=dynamic_cast<const DataArrayAsciiChar *>(&other);
2163   if(!otherC)
2164     { reason="this is of type DataArrayAsciiChar whereas other is not a DataArrayAsciiChar instance"; return false; }
2165   return DataArrayChar::isEqualIfNotWhy(other,reason);
2166 }
2167
2168 DataArrayAsciiCharIterator::DataArrayAsciiCharIterator(DataArrayAsciiChar *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
2169 {
2170   if(_da)
2171     {
2172       _da->incrRef();
2173       if(_da->isAllocated())
2174         {
2175           _nb_comp=da->getNumberOfComponents();
2176           _nb_tuple=da->getNumberOfTuples();
2177           _pt=da->getPointer();
2178         }
2179     }
2180 }
2181
2182 DataArrayAsciiCharIterator::~DataArrayAsciiCharIterator()
2183 {
2184   if(_da)
2185     _da->decrRef();
2186 }
2187
2188 DataArrayAsciiCharTuple *DataArrayAsciiCharIterator::nextt()
2189 {
2190   if(_tuple_id<_nb_tuple)
2191     {
2192       _tuple_id++;
2193       DataArrayAsciiCharTuple *ret=new DataArrayAsciiCharTuple(_pt,_nb_comp);
2194       _pt+=_nb_comp;
2195       return ret;
2196     }
2197   else
2198     return 0;
2199 }
2200
2201 DataArrayAsciiCharTuple::DataArrayAsciiCharTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
2202 {
2203 }
2204
2205 std::string DataArrayAsciiCharTuple::repr() const
2206 {
2207   std::ostringstream oss;
2208   std::copy(_pt,_pt+_nb_of_compo,std::ostream_iterator<char>(oss));
2209   return oss.str();
2210 }
2211
2212 char DataArrayAsciiCharTuple::asciiCharValue() const
2213 {
2214   if(_nb_of_compo==1)
2215     return *_pt;
2216   throw INTERP_KERNEL::Exception("DataArrayAsciiCharTuple::asciiCharValue : DataArrayAsciiCharTuple instance has not exactly 1 component -> Not possible to convert it into an character !");
2217 }
2218
2219 /*!
2220  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayAsciiChar::decrRef.
2221  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayAsciiChar::useArray with ownership set to \b false.
2222  * This method throws an INTERP_KERNEL::Exception is it is impossible to match sizes of \b this that is too say \b nbOfCompo=this->_nb_of_elem and \bnbOfTuples==1 or
2223  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
2224  */
2225 DataArrayAsciiChar *DataArrayAsciiCharTuple::buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const
2226 {
2227   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
2228     {
2229       DataArrayAsciiChar *ret=DataArrayAsciiChar::New();
2230       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
2231       return ret;
2232     }
2233   else
2234     {
2235       std::ostringstream oss; oss << "DataArrayAsciiCharTuple::buildDAAsciiChar : unable to build a requested DataArrayAsciiChar instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
2236       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
2237       throw INTERP_KERNEL::Exception(oss.str().c_str());
2238     }
2239 }