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