diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h index 56b21612e733f9bb6a2e33cc0f87fb6156102668..7ea874f698fab38654b6ec794d69b70eaee42f74 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h @@ -15,14 +15,14 @@ class GeoIntrusivePtr{ public: template <typename GeoTypeGrp> friend class GeoIntrusivePtr; - GeoIntrusivePtr() noexcept = default; + GeoIntrusivePtr() noexcept = default; // Standard constructor taking a bare pointer GeoIntrusivePtr(GeoType* obj) noexcept: m_ptr{obj} { if (m_ptr) obj->ref(); } /// Copy constructor - explicit GeoIntrusivePtr(const GeoIntrusivePtr& other) noexcept: + GeoIntrusivePtr(const GeoIntrusivePtr& other) noexcept: GeoIntrusivePtr{other.get()} {} /// Copy constructor for derived types @@ -32,16 +32,16 @@ class GeoIntrusivePtr{ GeoIntrusivePtr{other.get()} {} /// Move constructor - explicit GeoIntrusivePtr(GeoIntrusivePtr&& other) noexcept: - m_ptr{other.m_ptr} { - other.m_ptr = nullptr; + GeoIntrusivePtr(GeoIntrusivePtr&& other) noexcept: + GeoIntrusivePtr{} { + move(std::move(other)); } /// Move constructor for derived types template <typename GeoTypeGrp, typename = typename std::enable_if<!std::is_same<GeoType,GeoTypeGrp>::value, bool>> GeoIntrusivePtr(GeoIntrusivePtr<GeoTypeGrp>&& other) noexcept: - m_ptr{other.m_ptr} { - other.m_ptr = nullptr; + GeoIntrusivePtr{} { + move(std::move(other)); } @@ -62,24 +62,14 @@ class GeoIntrusivePtr{ return *this; } /// Move assignment operator - GeoIntrusivePtr& operator=(GeoIntrusivePtr&& other) { - if (m_ptr && m_ptr == other.get()) { - m_ptr->unref(); - } else { - m_ptr = other.get(); - } - other.m_ptr = nullptr; + GeoIntrusivePtr& operator=(GeoIntrusivePtr&& other) noexcept { + move(std::move(other)); return *this; } template <typename GeoTypeGrp, typename = typename std::enable_if<!std::is_same<GeoType,GeoTypeGrp>::value, bool>> - GeoIntrusivePtr& operator=(GeoIntrusivePtr<GeoTypeGrp>&& other) { - if (m_ptr && m_ptr == other.get()) { - m_ptr->unref(); - } else { - m_ptr = other.get(); - } - other.m_ptr = nullptr; + GeoIntrusivePtr& operator=(GeoIntrusivePtr<GeoTypeGrp>&& other) noexcept { + move(std::move(other)); return *this; } /// Reset the pointer @@ -89,6 +79,15 @@ class GeoIntrusivePtr{ m_ptr = ptr; if (m_ptr) m_ptr->ref(); } + template <class GeoTypeGrp> + void move(GeoIntrusivePtr<GeoTypeGrp>&& obj) { + if (m_ptr != obj.get()) { + if (m_ptr) m_ptr->unref(); + m_ptr = obj.m_ptr; + obj.m_ptr = nullptr; + } + obj.m_ptr = nullptr; + } /// Destructor ~GeoIntrusivePtr() { if (m_ptr) m_ptr->unref(); diff --git a/GeoModelCore/GeoModelKernel/tests/testGeoIntrusivePtr.cxx b/GeoModelCore/GeoModelKernel/tests/testGeoIntrusivePtr.cxx index f740299f33a66e4fac38112979f3b3c1868bcda3..29c1a5bfd2005efbd3f105b84c9e88e8b3853186 100644 --- a/GeoModelCore/GeoModelKernel/tests/testGeoIntrusivePtr.cxx +++ b/GeoModelCore/GeoModelKernel/tests/testGeoIntrusivePtr.cxx @@ -2,6 +2,7 @@ #include <GeoModelKernel/GeoFullPhysVol.h> +#include <GeoModelKernel/GeoTransform.h> #include <GeoModelKernel/GeoPhysVol.h> #include <GeoModelKernel/GeoBox.h> #include <iostream> @@ -65,6 +66,39 @@ int main(int argc, char *argv[]){ physVol4 = std::move(physVol3); CHECKCOUNT(physVol4, 2); } + + GeoIntrusivePtr<GeoPhysVol> world{new GeoPhysVol(nullptr)}; + world->add(new GeoTransform(GeoTrf::Translate3D(0.,0.,0 ))); + { + GeoIntrusivePtr<GeoFullPhysVol> childVol{new GeoFullPhysVol(nullptr)}; + world->add(childVol); + CHECKCOUNT(world, 1); + CHECKCOUNT(childVol, 2); + CHECKCOUNT(world, 1); + childVol->getAbsoluteTransform(); + CHECKCOUNT(childVol, 2); + CHECKCOUNT(world, 1); + childVol->getX(); + CHECKCOUNT(world, 1); + childVol->getDefX(); + CHECKCOUNT(world, 1); + childVol->getDefAbsoluteTransform(); + CHECKCOUNT(world, 1); + } + { + GeoIntrusivePtr<GeoPhysVol> childVol{new GeoPhysVol(nullptr)}; + world->add(childVol); + CHECKCOUNT(world, 1); + CHECKCOUNT(childVol, 2); + CHECKCOUNT(world, 1); + childVol->getX(); + CHECKCOUNT(world, 1); + childVol->getDefX(); + CHECKCOUNT(world, 1); + } + CHECKCOUNT(world, 1); + + return EXIT_SUCCESS; } #pragma clang diagnostic pop