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