]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Addition of iteration of DataArrayInt.
authorageay <ageay>
Mon, 22 Aug 2011 13:15:20 +0000 (13:15 +0000)
committerageay <ageay>
Mon, 22 Aug 2011 13:15:20 +0000 (13:15 +0000)
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling_Swig/MEDCoupling.i
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingTypemaps.i

index 7384f74fdc871000ebc54dfbd669754a12400b8a..09e9d7ff509212e9f8e9b2a481b1460b8e79d3ef 100644 (file)
@@ -3028,6 +3028,11 @@ void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
     }
 }
 
+DataArrayIntIterator *DataArrayInt::iterator()
+{
+  return new DataArrayIntIterator(this);
+}
+
 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
 {
   if(getNumberOfComponents()!=1)
@@ -3916,3 +3921,54 @@ void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, cons
         setInfoOnComponent(i,tinyInfoS[i+1].c_str());
     }
 }
+
+DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_tuple(new DataArrayIntTuple(da)),_tuple_id(0),_nb_tuple(0)
+{
+  if(_da)
+    {
+      _da->incrRef();
+      _nb_tuple=da->getNumberOfTuples();
+    }
+}
+
+DataArrayIntIterator::~DataArrayIntIterator()
+{
+  if(_da)
+    _da->decrRef();
+  delete _tuple;
+}
+
+DataArrayIntTuple *DataArrayIntIterator::nextt()
+{
+  if(_tuple_id<_nb_tuple)
+    {
+      _tuple_id++;
+      _tuple->next();
+      return _tuple;
+    }
+  else
+    return 0;
+}
+
+DataArrayIntTuple::DataArrayIntTuple(DataArrayInt *da):_pt(0),_nb_of_compo(0)
+{
+  if(da)
+    {
+      _nb_of_compo=da->getNumberOfComponents();
+      _pt=da->getPointer()-_nb_of_compo;
+    }
+}
+
+void DataArrayIntTuple::next()
+{
+  _pt+=_nb_of_compo;
+}
+
+std::string DataArrayIntTuple::repr() const
+{
+  std::ostringstream oss; oss << "(";
+  for(int i=0;i<_nb_of_compo-1;i++)
+    oss << _pt[i] << ", ";
+  oss << _pt[_nb_of_compo-1] << ")";
+  return oss.str();
+}
index 2da9f12f7387bb1596b182f4c0ca3e6f59124f2f..2022454840a1023116bc1903b7bf4e2d246667e5 100644 (file)
@@ -107,12 +107,12 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void checkNbOfElems(int nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception);
   protected:
     DataArray():_nb_of_tuples(-1) { }
   protected:
     static void CheckValueInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception);
     static void CheckClosingParInRange(int ref, int value, const char *msg) throw(INTERP_KERNEL::Exception);
-    static int GetNumberOfItemGivenBES(int begin, int end, int step, const char *msg) throw(INTERP_KERNEL::Exception);
   protected:
     int _nb_of_tuples;
     std::string _name;
@@ -250,6 +250,8 @@ namespace ParaMEDMEM
     MemArray<double> _mem;
   };
 
+  class DataArrayIntIterator;
+
   class DataArrayInt : public DataArray
   {
   public:
@@ -318,6 +320,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT int *getPointer() { return _mem.getPointer(); }
     MEDCOUPLING_EXPORT static void SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet);
     MEDCOUPLING_EXPORT const int *getConstPointer() const { return _mem.getConstPointer(); }
+    MEDCOUPLING_EXPORT DataArrayIntIterator *iterator();
     MEDCOUPLING_EXPORT const int *begin() const { return getConstPointer(); }
     MEDCOUPLING_EXPORT const int *end() const { return getConstPointer()+getNbOfElems(); }
     MEDCOUPLING_EXPORT DataArrayInt *getIdsEqual(int val) const throw(INTERP_KERNEL::Exception);
@@ -375,6 +378,35 @@ namespace ParaMEDMEM
   private:
     MemArray<int> _mem;
   };
+
+  class DataArrayIntTuple;
+
+  class DataArrayIntIterator
+  {
+  public:
+    DataArrayIntIterator(DataArrayInt *da);
+    ~DataArrayIntIterator();
+     DataArrayIntTuple *nextt();
+  private:
+    DataArrayInt *_da;
+    DataArrayIntTuple *_tuple;
+    int _tuple_id;
+    int _nb_tuple;
+  };
+
+  class DataArrayIntTuple
+  {
+  public:
+    DataArrayIntTuple(DataArrayInt *da);
+    void next();
+    std::string repr() const;
+    int getNumberOfCompo() const { return _nb_of_compo; }
+    const int *getConstPointer() const { return  _pt; }
+    int *getPointer() { return _pt; }
+  private:
+    int *_pt;
+    int _nb_of_compo;
+  };
 }
 
 #endif
index 2dacbbbf1d4dd0de44e4bc4196b2350bf4d4ea5b..ca14dcfab2999474e8534c474b4d43da90061244 100644 (file)
@@ -114,6 +114,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti;
 %newobject ParaMEDMEM::MEDCouplingFieldTemplate::New;
 %newobject ParaMEDMEM::DataArrayInt::New;
+%newobject ParaMEDMEM::DataArrayInt::__iter__;
 %newobject ParaMEDMEM::DataArrayInt::convertToDblArr;
 %newobject ParaMEDMEM::DataArrayInt::deepCpy;
 %newobject ParaMEDMEM::DataArrayInt::performCpy;
@@ -284,6 +285,9 @@ using namespace INTERP_KERNEL;
 %ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo;
 %ignore ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues;
 %ignore ParaMEDMEM::MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo;
+%ignore ParaMEDMEM::DataArrayIntIterator::nextt;
+%ignore ParaMEDMEM::DataArrayIntTuple::next;
+%ignore ParaMEDMEM::DataArrayIntTuple::repr;
 
 %nodefaultctor;
 
@@ -2389,6 +2393,245 @@ namespace ParaMEDMEM
    }
  };
 
+%extend ParaMEDMEM::DataArrayIntTuple
+{
+  std::string __str__() const
+  {
+    return self->repr();
+  }
+  
+  PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception)
+  {
+    int sw;
+    int singleVal;
+    std::vector<int> multiVal;
+    std::pair<int, std::pair<int,int> > slic;
+    ParaMEDMEM::DataArrayInt *daIntTyypp=0;
+    const int *pt=self->getConstPointer();
+    int nbc=self->getNumberOfCompo();
+    convertObjToPossibleCpp2(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp);
+    switch(sw)
+      {
+      case 1:
+        {
+          if(singleVal>=nbc)
+            {
+              std::ostringstream oss;
+              oss << "Requesting for id " << singleVal << " having only " << nbc << " components !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+          if(singleVal>=0)
+            return PyInt_FromLong(pt[singleVal]);
+          else
+            {
+              if(nbc+singleVal>0)
+                return PyInt_FromLong(pt[nbc+singleVal]);
+              else
+                {
+                  std::ostringstream oss;
+                  oss << "Requesting for id " << singleVal << " having only " << nbc << " components !";
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+                }
+            }
+        }
+      case 2:
+        {
+          PyObject *t=PyTuple_New(multiVal.size());
+          for(int j=0;j<(int)multiVal.size();j++)
+            {
+              int cid=multiVal[j];
+              if(cid>=nbc)
+                {
+                  std::ostringstream oss;
+                  oss << "Requesting for id #" << cid << " having only " << nbc << " components !";
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+                }
+              PyTuple_SetItem(t,j,PyInt_FromLong(pt[cid]));
+            }
+          return t;
+        }
+      case 3:
+          {
+            int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,"");
+            PyObject *t=PyTuple_New(sz);
+            for(int j=0;j<sz;j++)
+              PyTuple_SetItem(t,j,PyInt_FromLong(pt[slic.first+j*slic.second.second]));
+            return t;
+          }
+      default:
+        throw INTERP_KERNEL::Exception("DataArrayIntTuple::__getitem__ : unrecognized type entered !");
+      }
+  }
+
+  DataArrayIntTuple *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception)
+  {
+     const char msg[]="DataArrayIntTuple::__setitem__ : unrecognized type entered, int, slice, list<int>, tuple<int> !";
+     int sw1,sw2;
+     int singleValV;
+     std::vector<int> multiValV;
+     std::pair<int, std::pair<int,int> > slicV;
+     ParaMEDMEM::DataArrayIntTuple *daIntTyyppV=0;
+     int nbc=self->getNumberOfCompo();
+     convertObjToPossibleCpp22(value,nbc,sw1,singleValV,multiValV,slicV,daIntTyyppV);
+     int singleVal;
+     std::vector<int> multiVal;
+     std::pair<int, std::pair<int,int> > slic;
+     ParaMEDMEM::DataArrayInt *daIntTyypp=0;
+     int *pt=self->getPointer();
+     convertObjToPossibleCpp2(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp);
+     switch(sw2)
+       {
+       case 1:
+         {
+           if(singleVal>=nbc)
+            {
+              std::ostringstream oss;
+              oss << "Requesting for setting id # " << singleVal << " having only " << nbc << " components !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+           switch(sw1)
+             {
+             case 1:
+               {
+                 pt[singleVal]=singleValV;
+                 return self;
+               }
+             case 2:
+               {
+                 if(multiValV.size()!=1)
+                   {
+                     std::ostringstream oss;
+                     oss << "Requesting for setting id # " << singleVal << " with a list or tuple with size != 1 ! ";
+                     throw INTERP_KERNEL::Exception(oss.str().c_str());
+                   }
+                 pt[singleVal]=multiValV[0];
+                 return self;
+               }
+             case 4:
+               {
+                 pt[singleVal]=daIntTyyppV->getConstPointer()[0];
+                 return self;
+               }
+             default:
+               throw INTERP_KERNEL::Exception(msg);
+             }
+         }
+       case 2:
+         {
+           switch(sw1)
+             {
+             case 1:
+               {
+                 for(std::vector<int>::const_iterator it=multiVal.begin();it!=multiVal.end();it++)
+                   {
+                     if(*it>=nbc)
+                       {
+                         std::ostringstream oss;
+                         oss << "Requesting for setting id # " << *it << " having only " << nbc << " components !";
+                         throw INTERP_KERNEL::Exception(oss.str().c_str());
+                       }
+                     pt[*it]=singleValV;
+                   }
+                 return self;
+               }
+             case 2:
+               {
+                 if(multiVal.size()!=multiValV.size())
+                   {
+                     std::ostringstream oss;
+                     oss << "Mismatch length of during assignment : " << multiValV.size() << " != " << multiVal.size() << " !";
+                     throw INTERP_KERNEL::Exception(oss.str().c_str());
+                   }
+                 for(int i=0;i<multiVal.size();i++)
+                   {
+                     int pos=multiVal[i];
+                     if(pos>=nbc)
+                       {
+                         std::ostringstream oss;
+                         oss << "Requesting for setting id # " << pos << " having only " << nbc << " components !";
+                         throw INTERP_KERNEL::Exception(oss.str().c_str());
+                       }
+                     pt[multiVal[i]]=multiValV[i];
+                   }
+                 return self;
+               }
+             case 4:
+               {
+                 const int *ptV=daIntTyyppV->getConstPointer();
+                 if(nbc>daIntTyyppV->getNumberOfCompo())
+                   {
+                     std::ostringstream oss;
+                     oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !";
+                     throw INTERP_KERNEL::Exception(oss.str().c_str());
+                   }
+                 std::copy(ptV,ptV+nbc,pt);
+                 return self;
+               }
+             default:
+               throw INTERP_KERNEL::Exception(msg);
+             }
+         }
+       case 3:
+         {
+           int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,"");
+           switch(sw1)
+             {
+             case 1:
+               {
+                 for(int j=0;j<sz;j++)
+                   pt[slic.first+j*slic.second.second]=singleValV;
+                 return self;
+               }
+             case 2:
+               {
+                 if(sz!=multiValV.size())
+                   {
+                     std::ostringstream oss;
+                     oss << "Mismatch length of during assignment : " << multiValV.size() << " != " << sz << " !";
+                     throw INTERP_KERNEL::Exception(oss.str().c_str());
+                   }
+                 for(int j=0;j<sz;j++)
+                   pt[slic.first+j*slic.second.second]=multiValV[j];
+                 return self;
+               }
+             case 4:
+               {
+                 const int *ptV=daIntTyyppV->getConstPointer();
+                 if(sz>daIntTyyppV->getNumberOfCompo())
+                   {
+                     std::ostringstream oss;
+                     oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !";
+                     throw INTERP_KERNEL::Exception(oss.str().c_str());
+                   }
+                 for(int j=0;j<sz;j++)
+                   pt[slic.first+j*slic.second.second]=ptV[j];
+                 return self;
+               }
+             default:
+               throw INTERP_KERNEL::Exception(msg);
+             }
+         }
+       default:
+         throw INTERP_KERNEL::Exception(msg);
+       }
+   }
+}
+
+%extend ParaMEDMEM::DataArrayIntIterator
+{
+  PyObject *next()
+  {
+    DataArrayIntTuple *ret=self->nextt();
+    if(ret)
+      return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0);
+    else
+      {
+        PyErr_SetString(PyExc_StopIteration,"No more data.");
+        return 0;
+      }
+  }
+}
+
 %extend ParaMEDMEM::DataArrayInt
  {
    std::string __str__() const
@@ -2396,6 +2639,11 @@ namespace ParaMEDMEM
      return self->repr();
    }
 
+   DataArrayIntIterator *__iter__()
+   {
+     return self->iterator();
+   }
+
    PyObject *getDifferentValues(bool val) const throw(INTERP_KERNEL::Exception)
    {
      std::set<int> ret=self->getDifferentValues();
index 4773a0b0e476c2035a3de1ffd10570df1023b68d..2e9758664438cc92c98eb598e73a4ece09c2b5d5 100644 (file)
@@ -6280,6 +6280,64 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertEqual(da.getValues(),[7,7,7,3,8,8,7,7,7,9,14,20,12,17,26,7,7,7,18,23,38,21,26,44,24,29,70,27,32,76])
         pass
 
+    def testSwigDataArrayIntIterator1(self):
+        da=DataArrayInt.New()
+        da.alloc(12,1)
+        da.iota(2)
+        da.rearrange(3)
+        # __getitem__ testing
+        li=[]
+        for it in da:
+            li+=it[1:]
+            pass
+        self.assertEqual([3, 4, 6, 7, 9, 10, 12, 13],li)
+        li=[]
+        for it in da:
+            li+=[it[-1]]
+            pass
+        self.assertEqual([4, 7, 10, 13],li)
+        li=[]
+        for it in da:
+            li+=it[[2,1,0]]
+            pass
+        self.assertEqual([4, 3, 2, 7, 6, 5, 10, 9, 8, 13, 12, 11],li)
+        # __setitem__ testing
+        da3=da.deepCpy()
+        da2=DataArrayInt.New()
+        da2.alloc(12,1)
+        da2.iota(2002)
+        da2.rearrange(3)
+        it2=da2.__iter__()
+        i=0
+        for it in da:
+            pt=it2.next()
+            it[:]=pt
+            pass
+        self.assertTrue(da.isEqual(da2))
+        da=da3
+        da3=da.deepCpy()
+        #
+        for it in da:
+            it[:]=5
+            pass
+        da.rearrange(1)
+        self.assertTrue(da.isUniform(5))
+        da=da3
+        da3=da.deepCpy()
+        #
+        for it in da:
+            it[:]=[8,9,12]
+            pass
+        self.assertEqual([8, 9, 12, 8, 9, 12, 8, 9, 12, 8, 9, 12],da.getValues())
+        da=da3
+        da3=da.deepCpy()
+        #
+        for it in da:
+            it[2]=[7]
+            pass
+        self.assertEqual([2, 3, 7, 5, 6, 7, 8, 9, 7, 11, 12, 7],da.getValues())
+        pass
+
     def testDAIAggregateMulti1(self):
         a=DataArrayInt.New()
         a.setValues(range(4),2,2)
index 95c008d16988de4c91be6309838660ab94522193..cb8c39340e59eaca159ba88c8d1645f60720dcf1 100644 (file)
@@ -789,6 +789,74 @@ static void convertObjToPossibleCpp2(PyObject *value, int nbelem, int& sw, int&
   sw=4;
 }
 
+static void convertObjToPossibleCpp22(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector<int>& stdvecTyypp, std::pair<int, std::pair<int,int> >& p, ParaMEDMEM::DataArrayIntTuple *& daIntTyypp) throw(INTERP_KERNEL::Exception)
+{
+  sw=-1;
+  if(PyInt_Check(value))
+    {
+      iTyypp=(int)PyInt_AS_LONG(value);
+      sw=1;
+      return;
+    }
+  if(PyTuple_Check(value))
+    {
+      int size=PyTuple_Size(value);
+      stdvecTyypp.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyTuple_GetItem(value,i);
+          if(PyInt_Check(o))
+            stdvecTyypp[i]=(int)PyInt_AS_LONG(o);
+          else
+            {
+              std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not integer ! only tuples of integers accepted !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+      sw=2;
+      return;
+    }
+  if(PyList_Check(value))
+    {
+      int size=PyList_Size(value);
+      stdvecTyypp.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyList_GetItem(value,i);
+          if(PyInt_Check(o))
+            stdvecTyypp[i]=(int)PyInt_AS_LONG(o);
+          else
+            {
+              std::ostringstream oss; oss << "List as been detected but element #" << i << " is not integer ! only lists of integers accepted !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+      sw=2;
+      return;
+    }
+  if(PySlice_Check(value))
+    {
+      Py_ssize_t strt,stp,step;
+      PySliceObject *oC=reinterpret_cast<PySliceObject *>(value);
+      if(PySlice_GetIndices(oC,nbelem,&strt,&stp,&step)!=0)
+        {
+          std::ostringstream oss; oss << "Slice in subscriptable object DataArray invalid : number of elemnts is : " << nbelem;
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      p.first=strt;
+      p.second.first=stp;
+      p.second.second=step;
+      sw=3;
+      return ;
+    }
+  void *argp;
+  int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0);
+  if(!SWIG_IsOK(status))
+    throw INTERP_KERNEL::Exception("4 types accepted : integer, tuple of integer, list of integer, slice, DataArrayIntTuple");
+  daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp);
+  sw=4;
+}
+
 /*!
  * if value int -> cpp it sw=1
  * if value list[int] -> vt sw=2