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