From: Wolfgang Bangerth Date: Thu, 25 Jul 2024 23:51:33 +0000 (-0600) Subject: Add move operations to SmartPointer. X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9518b0d4ffbb585205b25455cda91f92b30162e9;p=dealii.git Add move operations to SmartPointer. --- 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 {