]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add move operations to SmartPointer.
authorWolfgang Bangerth <bangerth@colostate.edu>
Thu, 25 Jul 2024 23:51:33 +0000 (17:51 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Sat, 10 Aug 2024 03:57:21 +0000 (21:57 -0600)
include/deal.II/base/smartpointer.h

index caa8fc37347bb0d9119eaac58cac720a04673a6a..4c097cedc846a56822766ea429327f697b20aa83 100644 (file)
@@ -111,6 +111,11 @@ public:
    */
   SmartPointer(const SmartPointer<T, P> &tt);
 
+  /**
+   * Move constructor for SmartPointer.
+   */
+  SmartPointer(SmartPointer<T, P> &&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<T, P> &
   operator=(const SmartPointer<T, P> &tt);
 
+  /**
+   * Move assignment operator for SmartPointer.
+   */
+  SmartPointer<T, P> &
+  operator=(SmartPointer<T, P> &&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<T, P>::SmartPointer(const SmartPointer<T, P> &tt)
 
 
 
+template <typename T, typename P>
+inline SmartPointer<T, P>::SmartPointer(SmartPointer<T, P> &&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 <typename T, typename P>
 inline SmartPointer<T, P>::~SmartPointer()
 {
@@ -406,6 +433,36 @@ SmartPointer<T, P>::operator=(const SmartPointer<T, P> &tt)
 
 
 
+template <typename T, typename P>
+inline SmartPointer<T, P> &
+SmartPointer<T, P>::operator=(SmartPointer<T, P> &&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 <typename T, typename P>
 inline SmartPointer<T, P>::operator T *() const
 {

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.