From 9518b0d4ffbb585205b25455cda91f92b30162e9 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 25 Jul 2024 17:51:33 -0600 Subject: [PATCH] Add move operations to SmartPointer. --- include/deal.II/base/smartpointer.h | 57 +++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/include/deal.II/base/smartpointer.h b/include/deal.II/base/smartpointer.h index caa8fc3734..4c097cedc8 100644 --- a/include/deal.II/base/smartpointer.h +++ b/include/deal.II/base/smartpointer.h @@ -111,6 +111,11 @@ public: */ SmartPointer(const SmartPointer &tt); + /** + * Move constructor for SmartPointer. + */ + SmartPointer(SmartPointer &&tt) noexcept; + /** * Constructor taking a normal pointer. If possible, i.e. if the pointer is * not a null pointer, the constructor subscribes to the given object to @@ -158,6 +163,12 @@ public: SmartPointer & operator=(const SmartPointer &tt); + /** + * Move assignment operator for SmartPointer. + */ + SmartPointer & + operator=(SmartPointer &&tt) noexcept; + /** * Delete the object pointed to and set the pointer to nullptr. Note * that unlike what the documentation of the class describes, *this @@ -312,6 +323,22 @@ inline SmartPointer::SmartPointer(const SmartPointer &tt) +template +inline SmartPointer::SmartPointer(SmartPointer &&tt) noexcept + : t(tt.t) + , id(tt.id) + , pointed_to_object_is_alive(false) +{ + if (tt.pointed_to_object_is_alive && t != nullptr) + t->subscribe(&pointed_to_object_is_alive, id); + + // Release the rhs object as if we had moved all members away from + // it directly: + tt = nullptr; +} + + + template inline SmartPointer::~SmartPointer() { @@ -406,6 +433,36 @@ SmartPointer::operator=(const SmartPointer &tt) +template +inline SmartPointer & +SmartPointer::operator=(SmartPointer &&tt) noexcept +{ + // if objects on the left and right hand side of the operator= are + // the same, then this is a no-op + if (&tt != this) + { + // Let us unsubscribe from the current object + if (pointed_to_object_is_alive && t != nullptr) + t->unsubscribe(&pointed_to_object_is_alive, id); + + // Then reset to the new object, and subscribe to it, assuming + // that the the rhs points to anything in the first place: + if (tt.pointed_to_object_is_alive && tt != nullptr) + { + t = tt.get(); + t->subscribe(&pointed_to_object_is_alive, id); + } + else + t = nullptr; + + // Finally release the rhs object since we moved its contents + tt = nullptr; + } + return *this; +} + + + template inline SmartPointer::operator T *() const { -- 2.39.5