From 37085aded890a9d7559993697669e4dfdf0a1fa8 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de>
Date: Sun, 15 May 2022 13:13:07 +0200
Subject: [PATCH] try iterator

---
 Base/Types/OwningVector.h             | 40 +++++++++++----------
 Device/Mask/DetectorMask.cpp          |  6 ++--
 Device/Mask/DetectorMask.h            |  4 +--
 Device/Mask/IShape2D.h                |  1 +
 Sample/Aggregate/ParticleLayout.cpp   |  2 +-
 auto/Wrap/doxygenBase.i               | 26 ++++++++++++--
 auto/Wrap/doxygenDevice.i             |  3 ++
 auto/Wrap/libBornAgainDevice.py       |  2 +-
 auto/Wrap/libBornAgainDevice_wrap.cpp | 50 +++++++++++++++------------
 9 files changed, 84 insertions(+), 50 deletions(-)

diff --git a/Base/Types/OwningVector.h b/Base/Types/OwningVector.h
index a82f10d508b..29bd5881720 100644
--- a/Base/Types/OwningVector.h
+++ b/Base/Types/OwningVector.h
@@ -31,21 +31,23 @@
 //! The objects pointed to must posses a clone() function.
 
 template <class T>
-class OwningVector : public std::vector<T*> {
+class OwningVector : private std::vector<T*> {
     using super = std::vector<T*>;
 
 public:
     OwningVector() = default;
     ~OwningVector()
-        {
-            for(T* e: *this)
-                delete e;
-            super::clear();
-        }
+    {
+        for (T* e : *this)
+            delete e;
+        super::clear();
+    }
     OwningVector(const OwningVector& other)
         : super()
     {
-        copyOther(other);
+        super::reserve(other.size());
+        for (T* e : other)
+            super::emplace_back(e->clone());
     }
     OwningVector& operator=(const OwningVector& other)
     {
@@ -55,18 +57,20 @@ public:
         swap(*this, ret);
         return *this;
     }
-    T*& operator[](int) = delete;
-    T*const& operator[](int i) const { return super::operator[](i); }
-    void clear() = delete;
-    T* pop_back() = delete;
 
-private:
-    void copyOther(const OwningVector& other)
-    {
-        super::reserve(other.size());
-        for (const std::unique_ptr<T>& t : other)
-            super::emplace_back(t->clone());
-    }
+    void emplace_back(T* e) { super::emplace_back(e); }
+
+    size_t size() const { return super::size(); }
+    T* const& operator[](int i) const { return super::operator[](i); }
+    T* const& at(int i) const { return super::at(i); }
+    const T* back() const { return super::back(); }
+
+    class Iterator : public std::vector<T*>::iterator {};
+
+    Iterator begin() const { return super::begin(); }
+    Iterator end() const { return super::end(); }
+    Iterator begin() { return super::begin(); }
+    Iterator end() { return super::end(); }
 };
 
 #endif // BORNAGAIN_BASE_TYPES_OWNINGVECTOR_H
diff --git a/Device/Mask/DetectorMask.cpp b/Device/Mask/DetectorMask.cpp
index 1bc4e1597de..e4ec31bf19a 100644
--- a/Device/Mask/DetectorMask.cpp
+++ b/Device/Mask/DetectorMask.cpp
@@ -44,7 +44,7 @@ DetectorMask& DetectorMask::operator=(const DetectorMask& other)
 
 void DetectorMask::addMask(const IShape2D& shape, bool mask_value)
 {
-    m_shapes.push_back(shape.clone());
+    m_shapes.emplace_back(shape.clone());
     m_mask_of_shape.push_back(mask_value);
     m_mask_data.clear();
     m_number_of_masked_channels = 0;
@@ -90,7 +90,7 @@ const IShape2D* DetectorMask::getMaskShape(size_t mask_index, bool& mask_value)
     if (mask_index >= numberOfMasks())
         return nullptr;
     mask_value = m_mask_of_shape[mask_index];
-    return m_shapes[mask_index].get();
+    return m_shapes[mask_index];
 }
 
 void DetectorMask::process_masks()
@@ -106,7 +106,7 @@ void DetectorMask::process_masks()
         // setting mask to the data starting from last shape added
         bool is_masked(false);
         for (size_t i_shape = m_shapes.size(); i_shape > 0; --i_shape) {
-            const IShape2D* shape = m_shapes[i_shape - 1].get();
+            const IShape2D* const shape = m_shapes[i_shape - 1];
             if (shape->contains(binx, biny)) {
                 if (m_mask_of_shape[i_shape - 1])
                     is_masked = true;
diff --git a/Device/Mask/DetectorMask.h b/Device/Mask/DetectorMask.h
index 8f7ff14053c..cdd7e545964 100644
--- a/Device/Mask/DetectorMask.h
+++ b/Device/Mask/DetectorMask.h
@@ -19,7 +19,7 @@
 #include "Device/Mask/IShape2D.h"
 
 #ifndef SWIG
-#include "Base/Types/CloneableVector.h"
+#include "Base/Types/OwningVector.h"
 #endif
 
 class Histogram2D;
@@ -65,7 +65,7 @@ private:
     void process_masks();
 
 #ifndef SWIG
-    CloneableVector<IShape2D> m_shapes;
+    OwningVector<IShape2D> m_shapes;
 #endif
     std::vector<bool> m_mask_of_shape;
     OutputData<bool> m_mask_data;
diff --git a/Device/Mask/IShape2D.h b/Device/Mask/IShape2D.h
index fa9afee25f1..486e9c16823 100644
--- a/Device/Mask/IShape2D.h
+++ b/Device/Mask/IShape2D.h
@@ -29,6 +29,7 @@ public:
         : m_name(name)
     {
     }
+    ~IShape2D() override = default;
     IShape2D* clone() const override = 0;
 
     //! Returns true if point with given coordinates is inside or on border of the shape.
diff --git a/Sample/Aggregate/ParticleLayout.cpp b/Sample/Aggregate/ParticleLayout.cpp
index d3a997b7e48..bbe0ff06f78 100644
--- a/Sample/Aggregate/ParticleLayout.cpp
+++ b/Sample/Aggregate/ParticleLayout.cpp
@@ -29,7 +29,7 @@ ParticleLayout* ParticleLayout::clone() const
 {
     auto* result = new ParticleLayout();
 
-    for (const auto& particle : m_particles)
+    for (const IParticle*const particle : m_particles)
         result->addAndRegisterAbstractParticle(particle->clone());
 
     if (m_interparticle)
diff --git a/auto/Wrap/doxygenBase.i b/auto/Wrap/doxygenBase.i
index 37ff34e1411..fffc234879e 100644
--- a/auto/Wrap/doxygenBase.i
+++ b/auto/Wrap/doxygenBase.i
@@ -580,6 +580,10 @@ C++ includes: IPixel.h
 ";
 
 
+// File: classOwningVector_1_1Iterator.xml
+%feature("docstring") OwningVector::Iterator "";
+
+
 // File: classOwningVector.xml
 %feature("docstring") OwningVector "
 
@@ -601,10 +605,28 @@ C++ includes: OwningVector.h
 %feature("docstring")  OwningVector::OwningVector "OwningVector< T >::OwningVector(const OwningVector &other)
 ";
 
-%feature("docstring")  OwningVector::clear "void OwningVector< T >::clear()=delete
+%feature("docstring")  OwningVector::emplace_back "void OwningVector< T >::emplace_back(T *e)
+";
+
+%feature("docstring")  OwningVector::size "size_t OwningVector< T >::size() const
+";
+
+%feature("docstring")  OwningVector::at "T* const& OwningVector< T >::at(int i) const
+";
+
+%feature("docstring")  OwningVector::back "const T* OwningVector< T >::back() const
+";
+
+%feature("docstring")  OwningVector::begin "Iterator OwningVector< T >::begin() const
+";
+
+%feature("docstring")  OwningVector::end "Iterator OwningVector< T >::end() const
+";
+
+%feature("docstring")  OwningVector::begin "Iterator OwningVector< T >::begin()
 ";
 
-%feature("docstring")  OwningVector::pop_back "T* OwningVector< T >::pop_back()=delete
+%feature("docstring")  OwningVector::end "Iterator OwningVector< T >::end()
 ";
 
 
diff --git a/auto/Wrap/doxygenDevice.i b/auto/Wrap/doxygenDevice.i
index ec4276729bd..10c081602f3 100644
--- a/auto/Wrap/doxygenDevice.i
+++ b/auto/Wrap/doxygenDevice.i
@@ -1624,6 +1624,9 @@ C++ includes: IShape2D.h
 %feature("docstring")  IShape2D::IShape2D "IShape2D::IShape2D(const char *name)
 ";
 
+%feature("docstring")  IShape2D::~IShape2D "IShape2D::~IShape2D() override=default
+";
+
 %feature("docstring")  IShape2D::clone "IShape2D* IShape2D::clone() const override=0
 ";
 
diff --git a/auto/Wrap/libBornAgainDevice.py b/auto/Wrap/libBornAgainDevice.py
index 20deb845406..4ac819bf6d4 100644
--- a/auto/Wrap/libBornAgainDevice.py
+++ b/auto/Wrap/libBornAgainDevice.py
@@ -3301,6 +3301,7 @@ class IShape2D(libBornAgainBase.ICloneable):
     def __init__(self, *args, **kwargs):
         raise AttributeError("No constructor defined - class is abstract")
     __repr__ = _swig_repr
+    __swig_destroy__ = _libBornAgainDevice.delete_IShape2D
 
     def clone(self):
         r"""
@@ -3320,7 +3321,6 @@ class IShape2D(libBornAgainBase.ICloneable):
 
         """
         return _libBornAgainDevice.IShape2D_contains(self, *args)
-    __swig_destroy__ = _libBornAgainDevice.delete_IShape2D
 
 # Register IShape2D in _libBornAgainDevice:
 _libBornAgainDevice.IShape2D_swigregister(IShape2D)
diff --git a/auto/Wrap/libBornAgainDevice_wrap.cpp b/auto/Wrap/libBornAgainDevice_wrap.cpp
index 891f31997fe..7bd5bebc723 100644
--- a/auto/Wrap/libBornAgainDevice_wrap.cpp
+++ b/auto/Wrap/libBornAgainDevice_wrap.cpp
@@ -34647,6 +34647,28 @@ SWIGINTERN PyObject *FootprintSquare_swiginit(PyObject *SWIGUNUSEDPARM(self), Py
   return SWIG_Python_InitShadowInstance(args);
 }
 
+SWIGINTERN PyObject *_wrap_delete_IShape2D(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  IShape2D *arg1 = (IShape2D *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IShape2D, SWIG_POINTER_DISOWN |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IShape2D" "', argument " "1"" of type '" "IShape2D *""'"); 
+  }
+  arg1 = reinterpret_cast< IShape2D * >(argp1);
+  delete arg1;
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_IShape2D_clone(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IShape2D *arg1 = (IShape2D *) 0 ;
@@ -34806,28 +34828,6 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_delete_IShape2D(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
-  PyObject *resultobj = 0;
-  IShape2D *arg1 = (IShape2D *) 0 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
-  PyObject *swig_obj[1] ;
-  
-  if (!args) SWIG_fail;
-  swig_obj[0] = args;
-  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IShape2D, SWIG_POINTER_DISOWN |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_IShape2D" "', argument " "1"" of type '" "IShape2D *""'"); 
-  }
-  arg1 = reinterpret_cast< IShape2D * >(argp1);
-  delete arg1;
-  resultobj = SWIG_Py_Void();
-  return resultobj;
-fail:
-  return NULL;
-}
-
-
 SWIGINTERN PyObject *IShape2D_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
@@ -47860,6 +47860,11 @@ static PyMethodDef SwigMethods[] = {
 	 { "delete_FootprintSquare", _wrap_delete_FootprintSquare, METH_O, "delete_FootprintSquare(FootprintSquare self)"},
 	 { "FootprintSquare_swigregister", FootprintSquare_swigregister, METH_O, NULL},
 	 { "FootprintSquare_swiginit", FootprintSquare_swiginit, METH_VARARGS, NULL},
+	 { "delete_IShape2D", _wrap_delete_IShape2D, METH_O, "\n"
+		"delete_IShape2D(IShape2D self)\n"
+		"IShape2D::~IShape2D() override=default\n"
+		"\n"
+		""},
 	 { "IShape2D_clone", _wrap_IShape2D_clone, METH_O, "\n"
 		"IShape2D_clone(IShape2D self) -> IShape2D\n"
 		"IShape2D* IShape2D::clone() const override=0\n"
@@ -47873,7 +47878,6 @@ static PyMethodDef SwigMethods[] = {
 		"Returns true if area defined by two bins is inside or on border of polygon (more precisely, if mid point of two bins satisfy this condition). \n"
 		"\n"
 		""},
-	 { "delete_IShape2D", _wrap_delete_IShape2D, METH_O, "delete_IShape2D(IShape2D self)"},
 	 { "IShape2D_swigregister", IShape2D_swigregister, METH_O, NULL},
 	 { "new_Ellipse", _wrap_new_Ellipse, METH_VARARGS, "\n"
 		"Ellipse(double xcenter, double ycenter, double xradius, double yradius, double theta=0.0)\n"
-- 
GitLab