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