diff --git a/Base/Types/OwningVector.h b/Base/Types/OwningVector.h
index a82f10d508b9fc46d968213e4ea6b92562fd2a8e..29bd588172063a944e86252eede8da163f0a7cf9 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 1bc4e1597defe439c3fc817f45a1af2b1fbd5006..e4ec31bf19a0cd0a2bb4d7f6d92a5799eb3d2fd8 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 8f7ff14053c23b1fb3942dd6fed35dc5acdd9752..cdd7e54596467424c14cb5133da07977bcf8bcaf 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 fa9afee25f1eabc71a362499eeab6bd89c748deb..486e9c16823e01bd52610e2fe9a1c0d4adbe5f97 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 d3a997b7e48de7d63d21c3e8d76694789b9ac2e9..bbe0ff06f78c83be354739bd7837b6fe43394a7c 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 37ff34e14114ca89049a86ec4d19b6efc64af1b2..fffc234879e54fdcb10d4e4d847ffb24cf14302b 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 ec4276729bd06e748ac2275232666353ea2d9a49..10c081602f34f533206eb007cc4159526bd30176 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 20deb845406f0ccfd41a6e2378d8c3b8e0b4a72f..4ac819bf6d4a0229e29551aac71f84f214eab5b3 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 891f31997fe12ea36272f061bc4864eb1a5f9e08..7bd5bebc72375756e5b67a8e438d096126a86376 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"