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