- ret0->alloc(ret1->back(),1);
- pt=ret0->getPointer();
- for(int i=0;i<sz;i++)
- pt=std::copy(v[i].begin(),v[i].end(),pt);
- data=ret0.retn(); dataIndex=ret1.retn();
-}
-
-/*!
- * Returns a new DataArrayInt which contains a complement of elements of \a this
- * one-dimensional array. I.e. the result array contains all elements from the range [0,
- * \a nbOfElement) not present in \a this array.
- * \param [in] nbOfElement - maximal size of the result array.
- * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
- * array using decrRef() as it is no more needed.
- * \throw If \a this is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
- * nbOfElement ).
- */
-DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
- std::vector<bool> tmp(nbOfElement);
- const int *pt=getConstPointer();
- int nbOfTuples=getNumberOfTuples();
- for(const int *w=pt;w!=pt+nbOfTuples;w++)
- if(*w>=0 && *w<nbOfElement)
- tmp[*w]=true;
- else
- throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
- int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
- DataArrayInt *ret=DataArrayInt::New();
- ret->alloc(nbOfRetVal,1);
- int j=0;
- int *retPtr=ret->getPointer();
- for(int i=0;i<nbOfElement;i++)
- if(!tmp[i])
- retPtr[j++]=i;
- return ret;
-}
-
-/*!
- * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
- * from an \a other one-dimensional array.
- * \param [in] other - a DataArrayInt containing elements not to include in the result array.
- * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
- * caller is to delete this array using decrRef() as it is no more needed.
- * \throw If \a other is NULL.
- * \throw If \a other is not allocated.
- * \throw If \a other->getNumberOfComponents() != 1.
- * \throw If \a this is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- * \sa DataArrayInt::buildSubstractionOptimized()
- */
-DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
-{
- if(!other)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
- checkAllocated();
- other->checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
- if(other->getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
- const int *pt=getConstPointer();
- int nbOfTuples=getNumberOfTuples();
- std::set<int> s1(pt,pt+nbOfTuples);
- pt=other->getConstPointer();
- nbOfTuples=other->getNumberOfTuples();
- std::set<int> s2(pt,pt+nbOfTuples);
- std::vector<int> r;
- std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
- DataArrayInt *ret=DataArrayInt::New();
- ret->alloc((int)r.size(),1);
- std::copy(r.begin(),r.end(),ret->getPointer());
- return ret;
-}
-
-/*!
- * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
- * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
- *
- * \param [in] other an array with one component and expected to be sorted ascendingly.
- * \ret list of ids in \a this but not in \a other.
- * \sa DataArrayInt::buildSubstraction
- */
-DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
-{
- static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
- if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
- checkAllocated(); other->checkAllocated();
- if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
- if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
- const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
- const int *work1(pt1Bg),*work2(pt2Bg);
- MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
- for(;work1!=pt1End;work1++)
- {
- if(work2!=pt2End && *work1==*work2)
- work2++;
- else
- ret->pushBackSilent(*work1);
- }
- return ret.retn();
-}
-
-
-/*!
- * Returns a new DataArrayInt which contains all elements of \a this and a given
- * one-dimensional arrays. The result array does not contain any duplicates
- * and its values are sorted in ascending order.
- * \param [in] other - an array to unite with \a this one.
- * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
- * array using decrRef() as it is no more needed.
- * \throw If \a this or \a other is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- * \throw If \a other->getNumberOfComponents() != 1.
- */
-DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
-{
- std::vector<const DataArrayInt *>arrs(2);
- arrs[0]=this; arrs[1]=other;
- return BuildUnion(arrs);
-}
-
-
-/*!
- * Returns a new DataArrayInt which contains elements present in both \a this and a given
- * one-dimensional arrays. The result array does not contain any duplicates
- * and its values are sorted in ascending order.
- * \param [in] other - an array to intersect with \a this one.
- * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
- * array using decrRef() as it is no more needed.
- * \throw If \a this or \a other is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- * \throw If \a other->getNumberOfComponents() != 1.
- */
-DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
-{
- std::vector<const DataArrayInt *>arrs(2);
- arrs[0]=this; arrs[1]=other;
- return BuildIntersection(arrs);
-}
-
-/*!
- * This method can be applied on allocated with one component DataArrayInt instance.
- * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
- * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19]
- *
- * \return a newly allocated array that contain the result of the unique operation applied on \a this.
- * \throw if \a this is not allocated or if \a this has not exactly one component.
- * \sa DataArrayInt::buildUniqueNotSorted
- */
-DataArrayInt *DataArrayInt::buildUnique() const
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
- int nbOfTuples=getNumberOfTuples();
- MCAuto<DataArrayInt> tmp=deepCopy();
- int *data=tmp->getPointer();
- int *last=std::unique(data,data+nbOfTuples);
- MCAuto<DataArrayInt> ret=DataArrayInt::New();
- ret->alloc(std::distance(data,last),1);
- std::copy(data,last,ret->getPointer());
- return ret.retn();
-}
-
-/*!
- * This method can be applied on allocated with one component DataArrayInt instance.
- * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
- *
- * \return a newly allocated array that contain the result of the unique operation applied on \a this.
- *
- * \throw if \a this is not allocated or if \a this has not exactly one component.
- *
- * \sa DataArrayInt::buildUnique
- */
-DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
- int minVal,maxVal;
- getMinMaxValues(minVal,maxVal);
- std::vector<bool> b(maxVal-minVal+1,false);
- const int *ptBg(begin()),*endBg(end());
- MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
- for(const int *pt=ptBg;pt!=endBg;pt++)
- {
- if(!b[*pt-minVal])
- {
- ret->pushBackSilent(*pt);
- b[*pt-minVal]=true;
- }
- }
- ret->copyStringInfoFrom(*this);
- return ret.retn();
-}
-
-/*!
- * Returns a new DataArrayInt which contains size of every of groups described by \a this
- * "index" array. Such "index" array is returned for example by
- * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
- * "MEDCouplingUMesh::buildDescendingConnectivity" and
- * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
- * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
- * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
- * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
- * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
- * The caller is to delete this array using decrRef() as it is no more needed.
- * \throw If \a this is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- * \throw If \a this->getNumberOfTuples() < 2.
- *
- * \b Example: <br>
- * - this contains [1,3,6,7,7,9,15]
- * - result array contains [2,3,1,0,2,6],
- * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
- *
- * \sa DataArrayInt::computeOffsetsFull
- */
-DataArrayInt *DataArrayInt::deltaShiftIndex() const
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
- int nbOfTuples=getNumberOfTuples();
- if(nbOfTuples<2)
- throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
- const int *ptr=getConstPointer();
- DataArrayInt *ret=DataArrayInt::New();
- ret->alloc(nbOfTuples-1,1);
- int *out=ret->getPointer();
- std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
- return ret;
-}
-
-/*!
- * Modifies \a this one-dimensional array so that value of each element \a x
- * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
- * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
- * and components remains the same.<br>
- * This method is useful for allToAllV in MPI with contiguous policy. This method
- * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
- * this one.
- * \throw If \a this is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- *
- * \b Example: <br>
- * - Before \a this contains [3,5,1,2,0,8]
- * - After \a this contains [0,3,8,9,11,11]<br>
- * Note that the last element 19 = 11 + 8 is missing because size of \a this
- * array is retained and thus there is no space to store the last element.
- */
-void DataArrayInt::computeOffsets()
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
- int nbOfTuples=getNumberOfTuples();
- if(nbOfTuples==0)
- return ;
- int *work=getPointer();
- int tmp=work[0];
- work[0]=0;
- for(int i=1;i<nbOfTuples;i++)
- {
- int tmp2=work[i];
- work[i]=work[i-1]+tmp;
- tmp=tmp2;
- }
- declareAsNew();
-}
-
-
-/*!
- * Modifies \a this one-dimensional array so that value of each element \a x
- * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
- * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
- * components remains the same and number of tuples is inceamented by one.<br>
- * This method is useful for allToAllV in MPI with contiguous policy. This method
- * differs from computeOffsets() in that the number of tuples is changed by this one.
- * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
- * \throw If \a this is not allocated.
- * \throw If \a this->getNumberOfComponents() != 1.
- *
- * \b Example: <br>
- * - Before \a this contains [3,5,1,2,0,8]
- * - After \a this contains [0,3,8,9,11,11,19]<br>
- * \sa DataArrayInt::deltaShiftIndex
- */
-void DataArrayInt::computeOffsetsFull()
-{
- checkAllocated();
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
- int nbOfTuples=getNumberOfTuples();
- int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
- const int *work=getConstPointer();
- ret[0]=0;
- for(int i=0;i<nbOfTuples;i++)
- ret[i+1]=work[i]+ret[i];
- useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
- declareAsNew();
-}
-
-/*!
- * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
- * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
- * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
- * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
- * filling completely one of the ranges in \a this.
- *
- * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
- * \param [out] rangeIdsFetched the range ids fetched
- * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
- * \a idsInInputListThatFetch is a part of input \a listOfIds.
- *
- * \sa DataArrayInt::computeOffsetsFull
- *
- * \b Example: <br>
- * - \a this : [0,3,7,9,15,18]
- * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
- * - \a rangeIdsFetched result array: [0,2,4]
- * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
- * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
- * <br>
- */
-void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
-{
- if(!listOfIds)
- throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
- listOfIds->checkAllocated(); checkAllocated();
- if(listOfIds->getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
- if(getNumberOfComponents()!=1)
- throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
- MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
- MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
- const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
- const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
- while(tupPtr!=tupEnd && offPtr!=offEnd)
- {
- if(*tupPtr==*offPtr)
- {
- int i=offPtr[0];
- while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
- if(i==offPtr[1])
- {
- ret0->pushBackSilent((int)std::distance(offBg,offPtr));
- ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
- offPtr++;
- }
- }
- else
- { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
- }
- rangeIdsFetched=ret0.retn();
- idsInInputListThatFetch=ret1.retn();