1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCouplingMemArray.txx"
31 using namespace MEDCoupling;
33 template class DataArrayTemplate<char>;
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.
41 int DataArrayChar::getHashCode() const
44 std::size_t nbOfElems=getNbOfElems();
45 int ret=nbOfElems*65536;
50 const char *pt=begin();
51 for(std::size_t i=0;i<nbOfElems;i+=delta)
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.
62 bool DataArrayChar::isEqual(const DataArrayChar& other) const
65 return isEqualIfNotWhy(other,tmp);
69 * Equivalent to DataArrayChar::isEqual except that if false the reason of
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
76 bool DataArrayChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
78 if(!areInfoEqualsIfNotWhy(other,reason))
80 return _mem.isEqual(other._mem,0,reason);
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.
89 bool DataArrayChar::isEqualWithoutConsideringStr(const DataArrayChar& other) const
92 return _mem.isEqual(other._mem,0,tmp);
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.
100 void DataArrayChar::fillWithZero()
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.
110 std::string DataArrayChar::repr() const
112 std::ostringstream ret;
117 std::string DataArrayChar::reprZip() const
119 std::ostringstream ret;
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.
129 DataArrayInt *DataArrayChar::convertToIntArr() const
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);
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
149 bool DataArrayChar::isUniform(char val) const
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;
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.
171 * \if ENABLE_EXAMPLES
172 * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
174 * \ref py_mcdataarrayint_meldwith "Here is a Python example".
177 void DataArrayChar::meldWith(const DataArrayChar *other)
180 throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : DataArrayChar pointer in input is NULL !");
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));
190 const char *inp1=getConstPointer();
191 const char *inp2=other->getConstPointer();
192 for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
194 w=std::copy(inp1,inp1+nbOfComp1,w);
195 w=std::copy(inp2,inp2+nbOfComp2,w);
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);
205 * Creates a new DataArrayChar containing IDs (indices) of tuples holding value equal to a
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.
213 DataArrayInt *DataArrayChar::findIdsEqual(char val) const
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++)
223 ret->pushBackSilent(i);
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.
236 DataArrayInt *DataArrayChar::findIdsNotEqual(char val) const
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++)
246 ret->pushBackSilent(i);
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
256 int DataArrayChar::findIdSequence(const std::vector<char>& vals) const
259 int nbOfCompo=getNumberOfComponents();
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);
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.
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.
279 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
280 * \sa DataArrayChar::findIdSequence.
282 int DataArrayChar::findIdFirstEqualTuple(const std::vector<char>& tupl) const
285 int nbOfCompo=getNumberOfComponents();
287 throw INTERP_KERNEL::Exception("DataArrayChar::findIdFirstEqualTuple : 0 components in 'this' !");
288 if(nbOfCompo!=(int)tupl.size())
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());
293 const char *cptr=getConstPointer();
294 std::size_t nbOfVals=getNbOfElems();
295 for(const char *work=cptr;work!=cptr+nbOfVals;)
297 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
298 if(work!=cptr+nbOfVals)
300 if(std::distance(cptr,work)%nbOfCompo!=0)
303 return std::distance(cptr,work)/nbOfCompo;
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
317 bool DataArrayChar::presenceOfTuple(const std::vector<char>& tupl) const
319 return findIdFirstEqualTuple(tupl)!=-1;
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()
330 bool DataArrayChar::presenceOfValue(char value) const
332 return findIdFirstEqual(value)!=-1;
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
341 bool DataArrayChar::presenceOfValue(const std::vector<char>& vals) const
343 return findIdFirstEqual(vals)!=-1;
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
352 int DataArrayChar::findIdFirstEqual(char value) const
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);
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
371 int DataArrayChar::findIdFirstEqual(const std::vector<char>& vals) const
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);
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)
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.
394 DataArrayInt *DataArrayChar::findIdsInRange(char vmin, char vmax) const
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);
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
422 * \throw If either \a a1 or \a a2 is NULL.
423 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
425 DataArrayChar *DataArrayChar::Aggregate(const DataArrayChar *a1, const DataArrayChar *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;
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
443 * \throw If all arrays within \a arr are NULL.
444 * \throw If getNumberOfComponents() of arrays within \a arr.
446 DataArrayChar *DataArrayChar::Aggregate(const std::vector<const DataArrayChar *>& arr)
448 std::vector<const DataArrayChar *> a;
449 for(std::vector<const DataArrayChar *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
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++)
459 if((*it)->getNumberOfComponents()!=nbOfComp)
460 throw INTERP_KERNEL::Exception("DataArrayChar::Aggregate : Nb of components mismatch for array aggregation !");
461 nbt+=(*it)->getNumberOfTuples();
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]));
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
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()
488 DataArrayChar *DataArrayChar::Meld(const DataArrayChar *a1, const DataArrayChar *a2)
490 std::vector<const DataArrayChar *> arr(2);
491 arr[0]=a1; arr[1]=a2;
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
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.
510 DataArrayChar *DataArrayChar::Meld(const std::vector<const DataArrayChar *>& arr)
512 std::vector<const DataArrayChar *> a;
513 for(std::vector<const DataArrayChar *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
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();
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++)
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();
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++)
541 retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
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));
552 * Returns a new instance of DataArrayByte. The caller is to delete this array
553 * using decrRef() as it is no more needed.
555 DataArrayByte *DataArrayByte::New()
557 return new DataArrayByte;
560 DataArrayByteIterator *DataArrayByte::iterator()
562 return new DataArrayByteIterator(this);
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.
570 DataArrayByte *DataArrayByte::deepCopy() const
572 return new DataArrayByte(*this);
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).
582 DataArrayByte *DataArrayByte::performCopyOrIncrRef(bool dCpy) const
589 return const_cast<DataArrayByte *>(this);
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.
599 char DataArrayByte::byteValue() const
603 if(getNbOfElems()==1)
605 return *getConstPointer();
608 throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is allocated but number of elements is not equal to 1 !");
611 throw INTERP_KERNEL::Exception("DataArrayByte::byteValue : DataArrayByte instance is not allocated !");
614 DataArrayChar *DataArrayByte::buildEmptySpecializedDAChar() const
616 return DataArrayByte::New();
619 void DataArrayByte::reprStream(std::ostream& stream) const
621 stream << "Name of byte array : \"" << _name << "\"\n";
622 reprWithoutNameStream(stream);
625 void DataArrayByte::reprZipStream(std::ostream& stream) const
627 stream << "Name of byte array : \"" << _name << "\"\n";
628 reprZipWithoutNameStream(stream);
631 void DataArrayByte::reprWithoutNameStream(std::ostream& stream) const
633 DataArray::reprWithoutNameStream(stream);
634 if(_mem.reprHeader(getNumberOfComponents(),stream))
636 const char *data=begin();
637 int nbOfTuples=getNumberOfTuples();
638 int nbCompo=getNumberOfComponents();
639 for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
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
648 void DataArrayByte::reprZipWithoutNameStream(std::ostream& stream) const
650 DataArray::reprWithoutNameStream(stream);
651 _mem.reprZip(getNumberOfComponents(),stream);
654 void DataArrayByte::reprCppStream(const std::string& varName, std::ostream& stream) const
656 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
657 const char *data=getConstPointer();
658 stream << "DataArrayByte *" << varName << "=DataArrayByte::New();" << std::endl;
659 if(nbTuples*nbComp>=1)
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;
667 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
668 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
672 * Method that gives a quick overvien of \a this for python.
674 void DataArrayByte::reprQuickOverview(std::ostream& stream) const
676 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
677 stream << "DataArrayByte C++ instance at " << this << ". ";
680 int nbOfCompo=(int)_info_on_compo.size();
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);
688 stream << "Number of components : 0.";
691 stream << "*** No data allocated ****";
694 void DataArrayByte::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
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++)
707 for(int j=0;j<nbOfCompo;j++,data++)
710 if(j!=nbOfCompo-1) oss2 << ", ";
715 { oss2 << (int)*data; data++; }
716 if(i!=nbOfTuples-1) oss2 << ", ";
717 std::string oss3Str(oss2.str());
718 if(oss3Str.length()<maxNbOfByteInRepr)
729 bool DataArrayByte::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
731 const DataArrayByte *otherC=dynamic_cast<const DataArrayByte *>(&other);
733 { reason="this is of type DataArrayByte whereas other is not a DataArrayByte instance"; return false; }
734 return DataArrayChar::isEqualIfNotWhy(other,reason);
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.
742 std::vector<bool> DataArrayByte::toVectorOfBool() const
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++)
756 DataArrayByteIterator::DataArrayByteIterator(DataArrayByte *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
761 if(_da->isAllocated())
763 _nb_comp=da->getNumberOfComponents();
764 _nb_tuple=da->getNumberOfTuples();
765 _pt=da->getPointer();
770 DataArrayByteIterator::~DataArrayByteIterator()
776 DataArrayByteTuple *DataArrayByteIterator::nextt()
778 if(_tuple_id<_nb_tuple)
781 DataArrayByteTuple *ret=new DataArrayByteTuple(_pt,_nb_comp);
789 DataArrayByteTuple::DataArrayByteTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
793 std::string DataArrayByteTuple::repr() const
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] << ")";
802 char DataArrayByteTuple::byteValue() const
806 throw INTERP_KERNEL::Exception("DataArrayByteTuple::byteValue : DataArrayByteTuple instance has not exactly 1 component -> Not possible to convert it into an character !");
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.
815 DataArrayByte *DataArrayByteTuple::buildDAByte(int nbOfTuples, int nbOfCompo) const
817 if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
819 DataArrayByte *ret=DataArrayByte::New();
820 ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
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());
832 * Returns a new instance of DataArrayAsciiChar. The caller is to delete this array
833 * using decrRef() as it is no more needed.
835 DataArrayAsciiChar *DataArrayAsciiChar::New()
837 return new DataArrayAsciiChar;
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.
845 DataArrayAsciiChar *DataArrayAsciiChar::New(const std::string& st)
847 return new DataArrayAsciiChar(st);
851 * \param [in] st the string. This input string should have a length greater than 0. If not an excpetion will be thrown.
853 DataArrayAsciiChar::DataArrayAsciiChar(const std::string& st)
855 std::size_t lgth=st.length();
857 throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with string ! Size of input string is null !");
859 std::copy(st.begin(),st.begin()+lgth,getPointer());
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.
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.
872 * \throw If input \a vst is empty.
873 * \throw If all strings in \a vst are empty.
875 DataArrayAsciiChar *DataArrayAsciiChar::New(const std::vector<std::string>& vst, char defaultChar)
877 return new DataArrayAsciiChar(vst,defaultChar);
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.
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.
888 * \throw If input \a vst is empty.
889 * \throw If all strings in \a vst are empty.
891 DataArrayAsciiChar::DataArrayAsciiChar(const std::vector<std::string>& vst, char defaultChar)
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());
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)
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);
912 DataArrayAsciiCharIterator *DataArrayAsciiChar::iterator()
914 return new DataArrayAsciiCharIterator(this);
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.
922 DataArrayAsciiChar *DataArrayAsciiChar::deepCopy() const
924 return new DataArrayAsciiChar(*this);
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).
934 DataArrayAsciiChar *DataArrayAsciiChar::performCopyOrIncrRef(bool dCpy) const
941 return const_cast<DataArrayAsciiChar *>(this);
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.
951 char DataArrayAsciiChar::asciiCharValue() const
955 if(getNbOfElems()==1)
957 return *getConstPointer();
960 throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is allocated but number of elements is not equal to 1 !");
963 throw INTERP_KERNEL::Exception("DataArrayAsciiChar::asciiCharValue : DataArrayAsciiChar instance is not allocated !");
966 DataArrayChar *DataArrayAsciiChar::buildEmptySpecializedDAChar() const
968 return DataArrayAsciiChar::New();
971 void DataArrayAsciiChar::reprStream(std::ostream& stream) const
973 stream << "Name of ASCII char array : \"" << _name << "\"\n";
974 reprWithoutNameStream(stream);
977 void DataArrayAsciiChar::reprZipStream(std::ostream& stream) const
979 stream << "Name of ASCII char array : \"" << _name << "\"\n";
980 reprZipWithoutNameStream(stream);
983 void DataArrayAsciiChar::reprWithoutNameStream(std::ostream& stream) const
985 DataArray::reprWithoutNameStream(stream);
986 if(_mem.reprHeader(getNumberOfComponents(),stream))
988 const char *data=begin();
989 int nbOfTuples=getNumberOfTuples();
990 int nbCompo=getNumberOfComponents();
991 for(int i=0;i<nbOfTuples;i++,data+=nbCompo)
993 stream << "Tuple #" << i << " : \"";
994 std::copy(data,data+nbCompo,std::ostream_iterator<char>(stream));
1000 void DataArrayAsciiChar::reprZipWithoutNameStream(std::ostream& stream) const
1002 reprWithoutNameStream(stream);
1005 void DataArrayAsciiChar::reprCppStream(const std::string& varName, std::ostream& stream) const
1007 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1008 const char *data=getConstPointer();
1009 stream << "DataArrayAsciiChar *" << varName << "=DataArrayAsciiChar::New();" << std::endl;
1010 if(nbTuples*nbComp>=1)
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;
1018 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1019 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1023 * Method that gives a quick overvien of \a this for python.
1025 void DataArrayAsciiChar::reprQuickOverview(std::ostream& stream) const
1027 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1028 stream << "DataArrayAsciiChar C++ instance at " << this << ". ";
1031 int nbOfCompo=(int)_info_on_compo.size();
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);
1039 stream << "Number of components : 0.";
1042 stream << "*** No data allocated ****";
1045 void DataArrayAsciiChar::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
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++)
1056 for(int j=0;j<nbOfCompo;j++)
1057 if(data[j]<32) isAscii=false;
1061 for(int j=0;j<nbOfCompo;j++,data++)
1068 for(int j=0;j<nbOfCompo;j++,data++)
1071 if(j!=nbOfCompo-1) oss2 << ", ";
1075 if(i!=nbOfTuples-1) oss2 << ", ";
1076 std::string oss3Str(oss2.str());
1077 if(oss3Str.length()<maxNbOfByteInRepr)
1088 bool DataArrayAsciiChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const
1090 const DataArrayAsciiChar *otherC=dynamic_cast<const DataArrayAsciiChar *>(&other);
1092 { reason="this is of type DataArrayAsciiChar whereas other is not a DataArrayAsciiChar instance"; return false; }
1093 return DataArrayChar::isEqualIfNotWhy(other,reason);
1096 DataArrayAsciiCharIterator::DataArrayAsciiCharIterator(DataArrayAsciiChar *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
1101 if(_da->isAllocated())
1103 _nb_comp=da->getNumberOfComponents();
1104 _nb_tuple=da->getNumberOfTuples();
1105 _pt=da->getPointer();
1110 DataArrayAsciiCharIterator::~DataArrayAsciiCharIterator()
1116 DataArrayAsciiCharTuple *DataArrayAsciiCharIterator::nextt()
1118 if(_tuple_id<_nb_tuple)
1121 DataArrayAsciiCharTuple *ret=new DataArrayAsciiCharTuple(_pt,_nb_comp);
1129 DataArrayAsciiCharTuple::DataArrayAsciiCharTuple(char *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
1133 std::string DataArrayAsciiCharTuple::repr() const
1135 std::ostringstream oss;
1136 std::copy(_pt,_pt+_nb_of_compo,std::ostream_iterator<char>(oss));
1140 char DataArrayAsciiCharTuple::asciiCharValue() const
1144 throw INTERP_KERNEL::Exception("DataArrayAsciiCharTuple::asciiCharValue : DataArrayAsciiCharTuple instance has not exactly 1 component -> Not possible to convert it into an character !");
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.
1153 DataArrayAsciiChar *DataArrayAsciiCharTuple::buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const
1155 if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
1157 DataArrayAsciiChar *ret=DataArrayAsciiChar::New();
1158 ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
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());