Salome HOME
Fix merge errors post 8.3.0
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArrayChar.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22 #include "MCAuto.hxx"
23
24 #include <set>
25 #include <cmath>
26 #include <limits>
27 #include <numeric>
28 #include <algorithm>
29 #include <functional>
30
31 using namespace MEDCoupling;
32
33 template class MEDCoupling::MemArray<char>;
34 template class MEDCoupling::DataArrayTemplate<char>;
35
36 /*!
37  * Returns an integer value characterizing \a this array, which is useful for a quick
38  * comparison of many instances of DataArrayInt.
39  *  \return int - the hash value.
40  *  \throw If \a this is not allocated.
41  */
42 int DataArrayChar::getHashCode() const
43 {
44   checkAllocated();
45   std::size_t nbOfElems=getNbOfElems();
46   int ret=nbOfElems*65536;
47   int delta=3;
48   if(nbOfElems>48)
49     delta=nbOfElems/8;
50   int ret0=0;
51   const char *pt=begin();
52   for(std::size_t i=0;i<nbOfElems;i+=delta)
53     ret0+=pt[i];
54   return ret+ret0;
55 }
56
57 /*!
58  * Checks if \a this and another DataArrayChar are fully equal. For more info see
59  * \ref MEDCouplingArrayBasicsCompare.
60  *  \param [in] other - an instance of DataArrayChar to compare with \a this one.
61  *  \return bool - \a true if the two arrays are equal, \a false else.
62  */
63 bool DataArrayChar::isEqual(const DataArrayChar& other) const
64 {
65   std::string tmp;
66   return isEqualIfNotWhy(other,tmp);
67 }
68
69 /*!
70  * Equivalent to DataArrayChar::isEqual except that if false the reason of
71  * mismatch is given.
72  * 
73  * \param [in] other the instance to be compared with \a this
74  * \param [out] reason In case of inequality returns the reason.
75  * \sa DataArrayChar::isEqual
76  */
77 bool DataArrayChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
78 {
79   if(!areInfoEqualsIfNotWhy(other,reason))
80     return false;
81   return _mem.isEqual(other._mem,0,reason);
82 }
83
84 /*!
85  * Checks if values of \a this and another DataArrayChar are equal. For more info see
86  * \ref MEDCouplingArrayBasicsCompare.
87  *  \param [in] other - an instance of DataArrayChar to compare with \a this one.
88  *  \return bool - \a true if the values of two arrays are equal, \a false else.
89  */
90 bool DataArrayChar::isEqualWithoutConsideringStr(const DataArrayChar& other) const
91 {
92   std::string tmp;
93   return _mem.isEqual(other._mem,0,tmp);
94 }
95
96 /*!
97  * Assign zero to all values in \a this array. To know more on filling arrays see
98  * \ref MEDCouplingArrayFill.
99  * \throw If \a this is not allocated.
100  */
101 void DataArrayChar::fillWithZero()
102 {
103   fillWithValue(0);
104 }
105
106 /*!
107  * Returns a textual and human readable representation of \a this instance of
108  * DataArrayChar. This text is shown when a DataArrayChar is printed in Python.
109  *  \return std::string - text describing \a this DataArrayChar.
110  */
111 std::string DataArrayChar::repr() const
112 {
113   std::ostringstream ret;
114   reprStream(ret);
115   return ret.str();
116 }
117
118 std::string DataArrayChar::reprZip() const
119 {
120   std::ostringstream ret;
121   reprZipStream(ret);
122   return ret.str();
123 }
124
125 /*!
126  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
127  * array to the new one.
128  *  \return DataArrayInt * - the new instance of DataArrayChar.
129  */
130 DataArrayInt *DataArrayChar::convertToIntArr() const
131 {
132   checkAllocated();
133   DataArrayInt *ret=DataArrayInt::New();
134   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
135   std::size_t nbOfVals=getNbOfElems();
136   const char *src=getConstPointer();
137   int *dest=ret->getPointer();
138   std::copy(src,src+nbOfVals,dest);
139   ret->copyStringInfoFrom(*this);
140   return ret;
141 }
142
143 /*!
144  * Checks if all values in \a this array are equal to \a val.
145  *  \param [in] val - value to check equality of array values to.
146  *  \return bool - \a true if all values are \a val.
147  *  \throw If \a this is not allocated.
148  *  \throw If \a this->getNumberOfComponents() != 1
149  */
150 bool DataArrayChar::isUniform(char val) const
151 {
152   checkAllocated();
153   if(getNumberOfComponents()!=1)
154     throw INTERP_KERNEL::Exception("DataArrayChar::isUniform : must be applied on DataArrayChar with only one component, you can call 'rearrange' method before !");
155   int nbOfTuples=getNumberOfTuples();
156   const char *w=getConstPointer();
157   const char *end2=w+nbOfTuples;
158   for(;w!=end2;w++)
159     if(*w!=val)
160       return false;
161   return true;
162 }
163
164 /*!
165  * Appends components of another array to components of \a this one, tuple by tuple.
166  * So that the number of tuples of \a this array remains the same and the number of 
167  * components increases.
168  *  \param [in] other - the DataArrayChar to append to \a this one.
169  *  \throw If \a this is not allocated.
170  *  \throw If \a this and \a other arrays have different number of tuples.
171  *
172  *  \if ENABLE_EXAMPLES
173  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
174  *
175  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
176  *  \endif
177  */
178 void DataArrayChar::meldWith(const DataArrayChar *other)
179 {
180   if(!other)
181     throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : DataArrayChar pointer in input is NULL !");
182   checkAllocated();
183   other->checkAllocated();
184   int nbOfTuples=getNumberOfTuples();
185   if(nbOfTuples!=other->getNumberOfTuples())
186     throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : mismatch of number of tuples !");
187   int nbOfComp1=getNumberOfComponents();
188   int nbOfComp2=other->getNumberOfComponents();
189   char *newArr=(char *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(char));
190   char *w=newArr;
191   const char *inp1=getConstPointer();
192   const char *inp2=other->getConstPointer();
193   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
194     {
195       w=std::copy(inp1,inp1+nbOfComp1,w);
196       w=std::copy(inp2,inp2+nbOfComp2,w);
197     }
198   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
199   std::vector<int> compIds(nbOfComp2);
200   for(int i=0;i<nbOfComp2;i++)
201     compIds[i]=nbOfComp1+i;
202   copyPartOfStringInfoFrom2(compIds,*other);
203 }
204
205 /*!
206  * Creates a new DataArrayChar containing IDs (indices) of tuples holding value equal to a
207  * given one.
208  *  \param [in] val - the value to find within \a this.
209  *  \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this
210  *          array using decrRef() as it is no more needed.
211  *  \throw If \a this is not allocated.
212  *  \throw If \a this->getNumberOfComponents() != 1.
213  */
214 DataArrayInt *DataArrayChar::findIdsEqual(char val) const
215 {
216   checkAllocated();
217   if(getNumberOfComponents()!=1)
218     throw INTERP_KERNEL::Exception("DataArrayChar::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
219   const char *cptr=getConstPointer();
220   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
221   int nbOfTuples=getNumberOfTuples();
222   for(int i=0;i<nbOfTuples;i++,cptr++)
223     if(*cptr==val)
224       ret->pushBackSilent(i);
225   return ret.retn();
226 }
227
228 /*!
229  * Creates a new DataArrayChar containing IDs (indices) of tuples holding value \b not
230  * equal to a given one. 
231  *  \param [in] val - the value to ignore within \a this.
232  *  \return DataArrayChar * - a new instance of DataArrayChar. The caller is to delete this
233  *          array using decrRef() as it is no more needed.
234  *  \throw If \a this is not allocated.
235  *  \throw If \a this->getNumberOfComponents() != 1.
236  */
237 DataArrayInt *DataArrayChar::findIdsNotEqual(char val) const
238 {
239   checkAllocated();
240   if(getNumberOfComponents()!=1)
241     throw INTERP_KERNEL::Exception("DataArrayChar::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
242   const char *cptr=getConstPointer();
243   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
244   int nbOfTuples=getNumberOfTuples();
245   for(int i=0;i<nbOfTuples;i++,cptr++)
246     if(*cptr!=val)
247       ret->pushBackSilent(i);
248   return ret.retn();
249 }
250
251 /*!
252  * This method searches the sequence specified in input parameter \b vals in \b this.
253  * This works only for DataArrayChar having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
254  * This method differs from DataArrayChar::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayChar::findIdFirstEqualTuple.
255  * \sa DataArrayChar::findIdFirstEqualTuple
256  */
257 int DataArrayChar::findIdSequence(const std::vector<char>& vals) const
258 {
259   checkAllocated();
260   int nbOfCompo=getNumberOfComponents();
261   if(nbOfCompo!=1)
262     throw INTERP_KERNEL::Exception("DataArrayChar::findIdSequence : works only for DataArrayChar instance with one component !");
263   const char *cptr=getConstPointer();
264   std::size_t nbOfVals=getNbOfElems();
265   const char *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
266   if(loc!=cptr+nbOfVals)
267     return std::distance(cptr,loc);
268   return -1;
269 }
270
271 /*!
272  * This method is an extension of DataArrayChar::findIdFirstEqual method because this method works for DataArrayChar with
273  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
274  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
275  * If any the tuple id is returned. If not -1 is returned.
276  * 
277  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
278  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
279  *
280  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
281  * \sa DataArrayChar::findIdSequence.
282  */
283 int DataArrayChar::findIdFirstEqualTuple(const std::vector<char>& tupl) const
284 {
285   checkAllocated();
286   int nbOfCompo=getNumberOfComponents();
287   if(nbOfCompo==0)
288     throw INTERP_KERNEL::Exception("DataArrayChar::findIdFirstEqualTuple : 0 components in 'this' !");
289   if(nbOfCompo!=(int)tupl.size())
290     {
291       std::ostringstream oss; oss << "DataArrayChar::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
292       throw INTERP_KERNEL::Exception(oss.str().c_str());
293     }
294   const char *cptr=getConstPointer();
295   std::size_t nbOfVals=getNbOfElems();
296   for(const char *work=cptr;work!=cptr+nbOfVals;)
297     {
298       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
299       if(work!=cptr+nbOfVals)
300         {
301           if(std::distance(cptr,work)%nbOfCompo!=0)
302             work++;
303           else
304             return std::distance(cptr,work)/nbOfCompo;
305         }
306     }
307   return -1;
308 }
309
310 /*!
311  * This method is an extension of DataArrayChar::presenceOfValue method because this method works for DataArrayChar with
312  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
313  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
314  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
315  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
316  * \sa DataArrayChar::findIdFirstEqualTuple
317  */
318 bool DataArrayChar::presenceOfTuple(const std::vector<char>& tupl) const
319 {
320   return findIdFirstEqualTuple(tupl)!=-1;
321 }
322
323 /*!
324  * Returns \a true if a given value is present within \a this one-dimensional array.
325  *  \param [in] value - the value to find within \a this array.
326  *  \return bool - \a true in case if \a value is present within \a this array.
327  *  \throw If \a this is not allocated.
328  *  \throw If \a this->getNumberOfComponents() != 1.
329  *  \sa findIdFirstEqual()
330  */
331 bool DataArrayChar::presenceOfValue(char value) const
332 {
333   return findIdFirstEqual(value)!=-1;
334 }
335
336 /*!
337  * This method expects to be called when number of components of this is equal to one.
338  * This method returns true if it exists a tuple so that the value is contained in \b vals.
339  * If not any tuple contains one of the values contained in 'vals' false is returned.
340  * \sa DataArrayChar::findIdFirstEqual
341  */
342 bool DataArrayChar::presenceOfValue(const std::vector<char>& vals) const
343 {
344   return findIdFirstEqual(vals)!=-1;
345 }
346
347 /*!
348  * This method expects to be called when number of components of this is equal to one.
349  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
350  * If not any tuple contains \b value -1 is returned.
351  * \sa DataArrayChar::presenceOfValue
352  */
353 int DataArrayChar::findIdFirstEqual(char value) const
354 {
355   checkAllocated();
356   if(getNumberOfComponents()!=1)
357     throw INTERP_KERNEL::Exception("DataArrayChar::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
358   const char *cptr=getConstPointer();
359   int nbOfTuples=getNumberOfTuples();
360   const char *ret=std::find(cptr,cptr+nbOfTuples,value);
361   if(ret!=cptr+nbOfTuples)
362     return std::distance(cptr,ret);
363   return -1;
364 }
365
366 /*!
367  * This method expects to be called when number of components of this is equal to one.
368  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
369  * If not any tuple contains one of the values contained in 'vals' false is returned.
370  * \sa DataArrayChar::presenceOfValue
371  */
372 int DataArrayChar::findIdFirstEqual(const std::vector<char>& vals) const
373 {
374   checkAllocated();
375   if(getNumberOfComponents()!=1)
376     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
377   std::set<char> vals2(vals.begin(),vals.end());
378   const char *cptr=getConstPointer();
379   int nbOfTuples=getNumberOfTuples();
380   for(const char *w=cptr;w!=cptr+nbOfTuples;w++)
381     if(vals2.find(*w)!=vals2.end())
382       return std::distance(cptr,w);
383   return -1;
384 }
385
386 /*!
387  * This method works only on data array with one component.
388  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
389  * this[*id] in [\b vmin,\b vmax)
390  * 
391  * \param [in] vmin begin of range. This value is included in range.
392  * \param [in] vmax end of range. This value is \b not included in range.
393  * \return a newly allocated data array that the caller should deal with.
394  */
395 DataArrayInt *DataArrayChar::findIdsInRange(char vmin, char vmax) const
396 {
397   checkAllocated();
398   if(getNumberOfComponents()!=1)
399     throw INTERP_KERNEL::Exception("DataArrayChar::findIdsInRange : this must have exactly one component !");
400   const char *cptr=getConstPointer();
401   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1);
402   int nbOfTuples=getNumberOfTuples();
403   for(int i=0;i<nbOfTuples;i++,cptr++)
404     if(*cptr>=vmin && *cptr<vmax)
405       ret->pushBackSilent(i);
406   return ret.retn();
407 }
408
409 /*!
410  * Returns a new DataArrayChar by concatenating two given arrays, so that (1) the number
411  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
412  * offsetA2</em> and (2)
413  * the number of component in the result array is same as that of each of given arrays.
414  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
415  * Info on components is copied from the first of the given arrays. Number of components
416  * in the given arrays must be the same.
417  *  \param [in] a1 - an array to include in the result array.
418  *  \param [in] a2 - another array to include in the result array.
419  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
420  *  \return DataArrayChar * - the new instance of DataArrayChar.
421  *          The caller is to delete this result array using decrRef() as it is no more
422  *          needed.
423  *  \throw If either \a a1 or \a a2 is NULL.
424  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
425  */
426 DataArrayChar *DataArrayChar::Aggregate(const DataArrayChar *a1, const DataArrayChar *a2)
427 {
428   if(!a1 || !a2)
429     throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input DataArrayChar instance is NULL !");
430   std::vector<const DataArrayChar *> v(2); v[0]=a1; v[1]=a2;
431   return Aggregate(v);
432 }
433
434 /*!
435  * Returns a new DataArrayChar by concatenating all given arrays, so that (1) the number
436  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
437  * the number of component in the result array is same as that of each of given arrays.
438  * Info on components is copied from the first of the given arrays. Number of components
439  * in the given arrays must be  the same.
440  *  \param [in] arr - a sequence of arrays to include in the result array.
441  *  \return DataArrayChar * - the new instance of DataArrayChar.
442  *          The caller is to delete this result array using decrRef() as it is no more
443  *          needed.
444  *  \throw If all arrays within \a arr are NULL.
445  *  \throw If getNumberOfComponents() of arrays within \a arr.
446  */
447 DataArrayChar *DataArrayChar::Aggregate(const std::vector<const DataArrayChar *>& arr)
448 {
449   std::vector<const DataArrayChar *> a;
450   for(std::vector<const DataArrayChar *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
451     if(*it4)
452       a.push_back(*it4);
453   if(a.empty())
454     throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : input list must be NON EMPTY !");
455   std::vector<const DataArrayChar *>::const_iterator it=a.begin();
456   std::size_t nbOfComp((*it)->getNumberOfComponents());
457   int nbt=(*it++)->getNumberOfTuples();
458   for(int i=1;it!=a.end();it++,i++)
459     {
460       if((*it)->getNumberOfComponents()!=nbOfComp)
461         throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : Nb of components mismatch for array aggregation !");
462       nbt+=(*it)->getNumberOfTuples();
463     }
464   MCAuto<DataArrayChar> ret=a[0]->buildEmptySpecializedDAChar();
465   ret->alloc(nbt,nbOfComp);
466   char *pt=ret->getPointer();
467   for(it=a.begin();it!=a.end();it++)
468     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
469   ret->copyStringInfoFrom(*(a[0]));
470   return ret.retn();
471 }
472
473 /*!
474  * Returns a new DataArrayChar by aggregating two given arrays, so that (1) the number
475  * of components in the result array is a sum of the number of components of given arrays
476  * and (2) the number of tuples in the result array is same as that of each of given
477  * arrays. In other words the i-th tuple of result array includes all components of
478  * i-th tuples of all given arrays.
479  * Number of tuples in the given arrays must be the same.
480  *  \param [in] a1 - an array to include in the result array.
481  *  \param [in] a2 - another array to include in the result array.
482  *  \return DataArrayChar * - the new instance of DataArrayChar.
483  *          The caller is to delete this result array using decrRef() as it is no more
484  *          needed.
485  *  \throw If both \a a1 and \a a2 are NULL.
486  *  \throw If any given array is not allocated.
487  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
488  */
489 DataArrayChar *DataArrayChar::Meld(const DataArrayChar *a1, const DataArrayChar *a2)
490 {
491   std::vector<const DataArrayChar *> arr(2);
492   arr[0]=a1; arr[1]=a2;
493   return Meld(arr);
494 }
495
496 /*!
497  * Returns a new DataArrayChar by aggregating all given arrays, so that (1) the number
498  * of components in the result array is a sum of the number of components of given arrays
499  * and (2) the number of tuples in the result array is same as that of each of given
500  * arrays. In other words the i-th tuple of result array includes all components of
501  * i-th tuples of all given arrays.
502  * Number of tuples in the given arrays must be  the same.
503  *  \param [in] arr - a sequence of arrays to include in the result array.
504  *  \return DataArrayChar * - the new instance of DataArrayChar.
505  *          The caller is to delete this result array using decrRef() as it is no more
506  *          needed.
507  *  \throw If all arrays within \a arr are NULL.
508  *  \throw If any given array is not allocated.
509  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
510  */
511 DataArrayChar *DataArrayChar::Meld(const std::vector<const DataArrayChar *>& arr)
512 {
513   std::vector<const DataArrayChar *> a;
514   for(std::vector<const DataArrayChar *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
515     if(*it4)
516       a.push_back(*it4);
517   if(a.empty())
518     throw INTERP_KERNEL::Exception("DataArrayChar::Meld : array must be NON empty !");
519   std::vector<const DataArrayChar *>::const_iterator it;
520   for(it=a.begin();it!=a.end();it++)
521     (*it)->checkAllocated();
522   it=a.begin();
523   int nbOfTuples=(*it)->getNumberOfTuples();
524   std::vector<int> nbc(a.size());
525   std::vector<const char *> pts(a.size());
526   nbc[0]=(*it)->getNumberOfComponents();
527   pts[0]=(*it++)->getConstPointer();
528   for(int i=1;it!=a.end();it++,i++)
529     {
530       if(nbOfTuples!=(*it)->getNumberOfTuples())
531         throw INTERP_KERNEL::Exception("DataArrayChar::meld : mismatch of number of tuples !");
532       nbc[i]=(*it)->getNumberOfComponents();
533       pts[i]=(*it)->getConstPointer();
534     }
535   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
536   DataArrayChar *ret=a[0]->buildEmptySpecializedDAChar();
537   ret->alloc(nbOfTuples,totalNbOfComp);
538   char *retPtr=ret->getPointer();
539   for(int i=0;i<nbOfTuples;i++)
540     for(int j=0;j<(int)a.size();j++)
541       {
542         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
543         pts[j]+=nbc[j];
544       }
545   int k=0;
546   for(int i=0;i<(int)a.size();i++)
547     for(int j=0;j<nbc[i];j++,k++)
548       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
549   return ret;
550 }
551
552 /*!
553  * Returns a new instance of DataArrayByte. The caller is to delete this array
554  * using decrRef() as it is no more needed. 
555  */
556 DataArrayByte *DataArrayByte::New()
557 {
558   return new DataArrayByte;
559 }
560
561 DataArrayByteIterator *DataArrayByte::iterator()
562 {
563   return new DataArrayByteIterator(this);
564 }
565
566 /*!
567  * Returns a full copy of \a this. For more info on copying data arrays see
568  * \ref MEDCouplingArrayBasicsCopyDeep.
569  *  \return DataArrayByte * - a new instance of DataArrayByte.
570  */
571 DataArrayByte *DataArrayByte::deepCopy() const
572 {
573   return new DataArrayByte(*this);
574 }
575
576 /*!
577  * Returns either a \a deep or \a shallow copy of this array. For more info see
578  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
579  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
580  *  \return DataArrayByte * - either a new instance of DataArrayByte (if \a dCpy
581  *          == \a true) or \a this instance (if \a dCpy == \a false).
582  */
583 DataArrayByte *DataArrayByte::performCopyOrIncrRef(bool dCpy) const
584 {
585   if(dCpy)
586     return deepCopy();
587   else
588     {
589       incrRef();
590       return const_cast<DataArrayByte *>(this);
591     }
592 }
593
594 /*!
595  * Returns the only one value in \a this, if and only if number of elements
596  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
597  *  \return char - the sole value stored in \a this array.
598  *  \throw If at least one of conditions stated above is not fulfilled.
599  */
600 char DataArrayByte::byteValue() const
601 {
602   if(isAllocated())
603     {
604       if(getNbOfElems()==1)
605         {
606           return *getConstPointer();
607         }
608       else
609         throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is allocated but number of elements is not equal to 1 !");
610     }
611   else
612     throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is not allocated !");
613 }
614
615 DataArrayChar *DataArrayByte::buildEmptySpecializedDAChar() const
616 {
617   return DataArrayByte::New();
618 }
619
620 void DataArrayByte::reprStream(std::ostream& stream) const
621 {
622   stream << "Name of byte array : \"" << _name << "\"\n";
623   reprWithoutNameStream(stream);
624 }
625
626 void DataArrayByte::reprZipStream(std::ostream& stream) const
627 {
628   stream << "Name of byte array : \"" << _name << "\"\n";
629   reprZipWithoutNameStream(stream);
630 }
631
632 void DataArrayByte::reprWithoutNameStream(std::ostream& stream) const
633 {
634   DataArray::reprWithoutNameStream(stream);
635   if(_mem.reprHeader(getNumberOfComponents(),stream))
636     {
637       const char *data=begin();
638       int nbOfTuples=getNumberOfTuples();
639       int nbCompo=getNumberOfComponents();
640       for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
641         {
642           stream << "Tuple #" << i << " : ";
643           std::copy(data,data+nbCompo,std::ostream_iterator<int>(stream," "));//it is not a bug int here not char because it is not ASCII here contrary to DataArrayAsciiChar
644           stream << "\n";
645         }
646     }
647 }
648
649 void DataArrayByte::reprZipWithoutNameStream(std::ostream& stream) const
650 {
651   DataArray::reprWithoutNameStream(stream);
652   _mem.reprZip(getNumberOfComponents(),stream);
653 }
654
655 void DataArrayByte::reprCppStream(const std::string& varName, std::ostream& stream) const
656 {
657   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
658   const char *data=getConstPointer();
659   stream << "DataArrayByte *" << varName << "=DataArrayByte::New();" << std::endl;
660   if(nbTuples*nbComp>=1)
661     {
662       stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={";
663       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<char>(stream,","));
664       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
665       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
666     }
667   else
668     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
669   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
670 }
671
672 /*!
673  * Method that gives a quick overvien of \a this for python.
674  */
675 void DataArrayByte::reprQuickOverview(std::ostream& stream) const
676 {
677   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
678   stream << "DataArrayByte C++ instance at " << this << ". ";
679   if(isAllocated())
680     {
681       int nbOfCompo=(int)_info_on_compo.size();
682       if(nbOfCompo>=1)
683         {
684           int nbOfTuples=getNumberOfTuples();
685           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
686           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
687         }
688       else
689         stream << "Number of components : 0.";
690     }
691   else
692     stream << "*** No data allocated ****";
693 }
694
695 void DataArrayByte::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
696 {
697   const char *data=begin();
698   int nbOfTuples=getNumberOfTuples();
699   int nbOfCompo=(int)_info_on_compo.size();
700   std::ostringstream oss2; oss2 << "[";
701   std::string oss2Str(oss2.str());
702   bool isFinished=true;
703   for(int i=0;i<nbOfTuples && isFinished;i++)
704     {
705       if(nbOfCompo>1)
706         {
707           oss2 << "(";
708           for(int j=0;j<nbOfCompo;j++,data++)
709             {
710               oss2 << (int)*data;
711               if(j!=nbOfCompo-1) oss2 << ", ";
712             }
713           oss2 << ")";
714         }
715       else
716         { oss2 << (int)*data; data++; }
717       if(i!=nbOfTuples-1) oss2 << ", ";
718       std::string oss3Str(oss2.str());
719       if(oss3Str.length()<maxNbOfByteInRepr)
720         oss2Str=oss3Str;
721       else
722         isFinished=false;
723     }
724   stream << oss2Str;
725   if(!isFinished)
726     stream << "... ";
727   stream << "]";
728 }
729
730 bool DataArrayByte::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
731 {
732   const DataArrayByte *otherC=dynamic_cast<const DataArrayByte *>(&other);
733   if(!otherC)
734     { reason="this is of type DataArrayByte whereas other is not a DataArrayByte instance"; return false; }
735   return DataArrayChar::isEqualIfNotWhy(other,reason);
736 }
737
738 /*!
739  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
740  * \throw if \a this is not allocated.
741  * \throw if \a this has not exactly one component.
742  */
743 std::vector<bool> DataArrayByte::toVectorOfBool() const
744 {
745   checkAllocated();
746   if(getNumberOfComponents()!=1)
747     throw INTERP_KERNEL::Exception("DataArrayByte::toVectorOfBool : this method can be used only if this has one component !");
748   int nbt(getNumberOfTuples());
749   std::vector<bool> ret(nbt,false);
750   const char *pt(begin());
751   for(int i=0;i<nbt;i++,pt++)
752     if(*pt!=0)
753       ret[i]=true;
754   return ret;
755 }
756
757 DataArrayByteIterator::DataArrayByteIterator(DataArrayByte *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
758 {
759   if(_da)
760     {
761       _da->incrRef();
762       if(_da->isAllocated())
763         {
764           _nb_comp=da->getNumberOfComponents();
765           _nb_tuple=da->getNumberOfTuples();
766           _pt=da->getPointer();
767         }
768     }
769 }
770
771 DataArrayByteIterator::~DataArrayByteIterator()
772 {
773   if(_da)
774     _da->decrRef();
775 }
776
777 DataArrayByteTuple *DataArrayByteIterator::nextt()
778 {
779   if(_tuple_id<_nb_tuple)
780     {
781       _tuple_id++;
782       DataArrayByteTuple *ret=new DataArrayByteTuple(_pt,_nb_comp);
783       _pt+=_nb_comp;
784       return ret;
785     }
786   else
787     return 0;
788 }
789
790 DataArrayByteTuple::DataArrayByteTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
791 {
792 }
793
794 std::string DataArrayByteTuple::repr() const
795 {
796   std::ostringstream oss; oss << "(";
797   for(int i=0;i<_nb_of_compo-1;i++)
798     oss << (int)_pt[i] << ", ";
799   oss << _pt[_nb_of_compo-1] << ")";
800   return oss.str();
801 }
802
803 char DataArrayByteTuple::byteValue() const
804 {
805   if(_nb_of_compo==1)
806     return *_pt;
807   throw INTERP_KERNEL::Exception("DataArrayByteTuple::byteValue : DataArrayByteTuple instance has not exactly 1 component -> Not possible to convert it into an character !");
808 }
809
810 /*!
811  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayByte::decrRef.
812  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayByte::useArray with ownership set to \b false.
813  * 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
814  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
815  */
816 DataArrayByte *DataArrayByteTuple::buildDAByte(int nbOfTuples, int nbOfCompo) const
817 {
818   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
819     {
820       DataArrayByte *ret=DataArrayByte::New();
821       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
822       return ret;
823     }
824   else
825     {
826       std::ostringstream oss; oss << "DataArrayByteTuple::buildDAByte : unable to build a requested DataArrayByte instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
827       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
828       throw INTERP_KERNEL::Exception(oss.str().c_str());
829     }
830 }
831
832 /*!
833  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
834  * using decrRef() as it is no more needed. 
835  */
836 DataArrayAsciiChar *DataArrayAsciiChar::New()
837 {
838   return new DataArrayAsciiChar;
839 }
840
841 /*!
842  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
843  * using decrRef() as it is no more needed. 
844  * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown.
845  */
846 DataArrayAsciiChar *DataArrayAsciiChar::New(const std::string& st)
847 {
848   return new DataArrayAsciiChar(st);
849 }
850
851 /*!
852  * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown.
853  */
854 DataArrayAsciiChar::DataArrayAsciiChar(const std::string& st)
855 {
856   std::size_t lgth=st.length();
857   if(lgth==0)
858     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with string ! Size of input string is null !");
859   alloc(1,lgth);
860   std::copy(st.begin(),st.begin()+lgth,getPointer());
861 }
862
863 /*!
864  * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
865  * using decrRef() as it is no more needed. 
866  * 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
867  * \a vst the remaining locations in memory will be set to character \a defaultChar.
868  *
869  * \param [in] defaultChar the default character used to fill not defined locations in \a this
870  * \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
871  *             in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown.
872  *
873  * \throw If input \a vst is empty.
874  * \throw If all strings in \a vst are empty.
875  */
876 DataArrayAsciiChar *DataArrayAsciiChar::New(const std::vector<std::string>& vst, char defaultChar)
877 {
878   return new DataArrayAsciiChar(vst,defaultChar);
879 }
880
881 /*!
882  * 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
883  * \a vst the remaining locations in memory will be set to character \a defaultChar.
884  *
885  * \param [in] defaultChar the default character used to fill not defined locations in \a this
886  * \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
887  *             in \a vst. If all strings are empty an INTERP_KERNEL::Exception will be thrown.
888  *
889  * \throw If input \a vst is empty.
890  * \throw If all strings in \a vst are empty.
891  */
892 DataArrayAsciiChar::DataArrayAsciiChar(const std::vector<std::string>& vst, char defaultChar)
893 {
894   if(vst.empty())
895     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! Empty array !");
896   std::size_t nbCompo=0;
897   for(std::vector<std::string>::const_iterator it=vst.begin();it!=vst.end();it++)
898     nbCompo=std::max(nbCompo,(*it).length());
899   if(nbCompo==0)
900     throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! All strings in not empty vector are empty !");
901   int nbTuples=(int)vst.size();
902   alloc(nbTuples,(int)nbCompo);
903   char *pt=getPointer();
904   for(int i=0;i<nbTuples;i++,pt+=nbCompo)
905     {
906       const std::string& tmp=vst[i];
907       std::size_t sz=tmp.length();
908       std::copy(tmp.begin(),tmp.begin()+sz,pt);
909       std::fill(pt+sz,pt+nbCompo,defaultChar);
910     }
911 }
912
913 DataArrayAsciiCharIterator *DataArrayAsciiChar::iterator()
914 {
915   return new DataArrayAsciiCharIterator(this);
916 }
917
918 /*!
919  * Returns a full copy of \a this. For more info on copying data arrays see
920  * \ref MEDCouplingArrayBasicsCopyDeep.
921  *  \return DataArrayAsciiChar * - a new instance of DataArrayAsciiChar.
922  */
923 DataArrayAsciiChar *DataArrayAsciiChar::deepCopy() const
924 {
925   return new DataArrayAsciiChar(*this);
926 }
927
928 /*!
929  * Returns either a \a deep or \a shallow copy of this array. For more info see
930  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
931  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
932  *  \return DataArrayAsciiChar * - either a new instance of DataArrayAsciiChar (if \a dCpy
933  *          == \a true) or \a this instance (if \a dCpy == \a false).
934  */
935 DataArrayAsciiChar *DataArrayAsciiChar::performCopyOrIncrRef(bool dCpy) const
936 {
937   if(dCpy)
938     return deepCopy();
939   else
940     {
941       incrRef();
942       return const_cast<DataArrayAsciiChar *>(this);
943     }
944 }
945
946 /*!
947  * Returns the only one value in \a this, if and only if number of elements
948  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
949  *  \return char - the sole value stored in \a this array.
950  *  \throw If at least one of conditions stated above is not fulfilled.
951  */
952 char DataArrayAsciiChar::asciiCharValue() const
953 {
954   if(isAllocated())
955     {
956       if(getNbOfElems()==1)
957         {
958           return *getConstPointer();
959         }
960       else
961         throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is allocated but number of elements is not equal to 1 !");
962     }
963   else
964     throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is not allocated !");
965 }
966
967 DataArrayChar *DataArrayAsciiChar::buildEmptySpecializedDAChar() const
968 {
969   return DataArrayAsciiChar::New();
970 }
971
972 void DataArrayAsciiChar::reprStream(std::ostream& stream) const
973 {
974   stream << "Name of ASCII char array : \"" << _name << "\"\n";
975   reprWithoutNameStream(stream);
976 }
977
978 void DataArrayAsciiChar::reprZipStream(std::ostream& stream) const
979 {
980   stream << "Name of ASCII char array : \"" << _name << "\"\n";
981   reprZipWithoutNameStream(stream);
982 }
983
984 void DataArrayAsciiChar::reprWithoutNameStream(std::ostream& stream) const
985 {
986   DataArray::reprWithoutNameStream(stream);
987   if(_mem.reprHeader(getNumberOfComponents(),stream))
988     {
989       const char *data=begin();
990       int nbOfTuples=getNumberOfTuples();
991       int nbCompo=getNumberOfComponents();
992       for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
993         {
994           stream << "Tuple #" << i << " : \"";
995           std::copy(data,data+nbCompo,std::ostream_iterator<char>(stream));
996           stream << "\"\n";
997         }
998     }
999 }
1000
1001 void DataArrayAsciiChar::reprZipWithoutNameStream(std::ostream& stream) const
1002 {
1003   reprWithoutNameStream(stream);
1004 }
1005
1006 void DataArrayAsciiChar::reprCppStream(const std::string& varName, std::ostream& stream) const
1007 {
1008   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1009   const char *data=getConstPointer();
1010   stream << "DataArrayAsciiChar *" << varName << "=DataArrayAsciiChar::New();" << std::endl;
1011   if(nbTuples*nbComp>=1)
1012     {
1013       stream << "const char " << varName << "Data[" << nbTuples*nbComp << "]={";
1014       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<char>(stream,","));
1015       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1016       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1017     }
1018   else
1019     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1020   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1021 }
1022
1023 /*!
1024  * Method that gives a quick overvien of \a this for python.
1025  */
1026 void DataArrayAsciiChar::reprQuickOverview(std::ostream& stream) const
1027 {
1028   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1029   stream << "DataArrayAsciiChar C++ instance at " << this << ". ";
1030   if(isAllocated())
1031     {
1032       int nbOfCompo=(int)_info_on_compo.size();
1033       if(nbOfCompo>=1)
1034         {
1035           int nbOfTuples=getNumberOfTuples();
1036           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1037           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1038         }
1039       else
1040         stream << "Number of components : 0.";
1041     }
1042   else
1043     stream << "*** No data allocated ****";
1044 }
1045
1046 void DataArrayAsciiChar::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1047 {
1048   const char *data=begin();
1049   int nbOfTuples=getNumberOfTuples();
1050   int nbOfCompo=(int)_info_on_compo.size();
1051   std::ostringstream oss2; oss2 << "[";
1052   std::string oss2Str(oss2.str());
1053   bool isFinished=true;
1054   for(int i=0;i<nbOfTuples && isFinished;i++)
1055     {
1056       bool isAscii=true;
1057       for(int j=0;j<nbOfCompo;j++)
1058         if(data[j]<32) isAscii=false;
1059       if(isAscii)
1060         {
1061           oss2 << "\'";
1062           for(int j=0;j<nbOfCompo;j++,data++)
1063             oss2 << *data;
1064           oss2 << "\'";
1065         }
1066       else
1067         {
1068           oss2 << "(";
1069           for(int j=0;j<nbOfCompo;j++,data++)
1070             {
1071               oss2 << (int)*data;
1072               if(j!=nbOfCompo-1) oss2 << ", ";
1073             }
1074           oss2 << ")";
1075         }
1076       if(i!=nbOfTuples-1) oss2 << ", ";
1077       std::string oss3Str(oss2.str());
1078       if(oss3Str.length()<maxNbOfByteInRepr)
1079         oss2Str=oss3Str;
1080       else
1081         isFinished=false;
1082     }
1083   stream << oss2Str;
1084   if(!isFinished)
1085     stream << "... ";
1086   stream << "]";
1087 }
1088
1089 bool DataArrayAsciiChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
1090 {
1091   const DataArrayAsciiChar *otherC=dynamic_cast<const DataArrayAsciiChar *>(&other);
1092   if(!otherC)
1093     { reason="this is of type DataArrayAsciiChar whereas other is not a DataArrayAsciiChar instance"; return false; }
1094   return DataArrayChar::isEqualIfNotWhy(other,reason);
1095 }
1096
1097 DataArrayAsciiCharIterator::DataArrayAsciiCharIterator(DataArrayAsciiChar *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
1098 {
1099   if(_da)
1100     {
1101       _da->incrRef();
1102       if(_da->isAllocated())
1103         {
1104           _nb_comp=da->getNumberOfComponents();
1105           _nb_tuple=da->getNumberOfTuples();
1106           _pt=da->getPointer();
1107         }
1108     }
1109 }
1110
1111 DataArrayAsciiCharIterator::~DataArrayAsciiCharIterator()
1112 {
1113   if(_da)
1114     _da->decrRef();
1115 }
1116
1117 DataArrayAsciiCharTuple *DataArrayAsciiCharIterator::nextt()
1118 {
1119   if(_tuple_id<_nb_tuple)
1120     {
1121       _tuple_id++;
1122       DataArrayAsciiCharTuple *ret=new DataArrayAsciiCharTuple(_pt,_nb_comp);
1123       _pt+=_nb_comp;
1124       return ret;
1125     }
1126   else
1127     return 0;
1128 }
1129
1130 DataArrayAsciiCharTuple::DataArrayAsciiCharTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
1131 {
1132 }
1133
1134 std::string DataArrayAsciiCharTuple::repr() const
1135 {
1136   std::ostringstream oss;
1137   std::copy(_pt,_pt+_nb_of_compo,std::ostream_iterator<char>(oss));
1138   return oss.str();
1139 }
1140
1141 char DataArrayAsciiCharTuple::asciiCharValue() const
1142 {
1143   if(_nb_of_compo==1)
1144     return *_pt;
1145   throw INTERP_KERNEL::Exception("DataArrayAsciiCharTuple::asciiCharValue : DataArrayAsciiCharTuple instance has not exactly 1 component -> Not possible to convert it into an character !");
1146 }
1147
1148 /*!
1149  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayAsciiChar::decrRef.
1150  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayAsciiChar::useArray with ownership set to \b false.
1151  * 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
1152  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
1153  */
1154 DataArrayAsciiChar *DataArrayAsciiCharTuple::buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const
1155 {
1156   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
1157     {
1158       DataArrayAsciiChar *ret=DataArrayAsciiChar::New();
1159       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
1160       return ret;
1161     }
1162   else
1163     {
1164       std::ostringstream oss; oss << "DataArrayAsciiCharTuple::buildDAAsciiChar : unable to build a requested DataArrayAsciiChar instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
1165       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
1166       throw INTERP_KERNEL::Exception(oss.str().c_str());
1167     }
1168 }