[libsigc++2] C++11 slot_base: Add move operations.



commit 0714b2d3de27fd2ea78caf824783aed3c18a8913
Author: Murray Cumming <murrayc murrayc com>
Date:   Tue Sep 1 14:29:08 2015 +0200

    C++11 slot_base: Add move operations.
    
    Improvements welcome.

 sigc++/functors/slot_base.cc |   69 ++++++++++++++++++++++++++++++-----------
 sigc++/functors/slot_base.h  |    7 ++++
 2 files changed, 57 insertions(+), 19 deletions(-)
---
diff --git a/sigc++/functors/slot_base.cc b/sigc++/functors/slot_base.cc
index 4bcfeb7..2bc0d40 100644
--- a/sigc++/functors/slot_base.cc
+++ b/sigc++/functors/slot_base.cc
@@ -125,6 +125,15 @@ slot_base::slot_base(const slot_base& src)
   }
 }
 
+slot_base::slot_base(slot_base&& src) noexcept
+: rep_(std::move(src.rep_)),
+  blocked_(std::move(src.blocked_))
+{
+  //Wipe src:
+  src.rep_ = nullptr;
+  src.blocked_ = false;
+}
+
 slot_base::~slot_base()
 {
   if (rep_)
@@ -136,6 +145,29 @@ slot_base::operator bool() const
   return rep_ != nullptr;
 }
 
+void slot_base::delete_rep_with_check()
+{
+  if (!rep_)
+    return;
+
+  // Make sure we are notified if disconnect() deletes rep_, which is trackable.
+  // Compare slot_rep::notify().
+  destroy_notify_struct notifier;
+  rep_->add_destroy_notify_callback(&notifier, destroy_notify_struct::notify);
+  rep_->disconnect(); // Disconnect the slot (might lead to deletion of rep_!).
+
+  // If rep_ has been deleted, don't try to delete it again.
+  // If it has been deleted, this slot_base has probably also been deleted, so
+  // don't clear the rep_ pointer. It's the responsibility of the code that
+  // deletes rep_ to either clear the rep_ pointer or delete this slot_base.
+  if (!notifier.deleted_)
+  {
+    rep_->remove_destroy_notify_callback(&notifier);
+    delete rep_; // Detach the stored functor from the other referred trackables and destroy it.
+    rep_ = nullptr;
+  }
+}
+
 slot_base& slot_base::operator=(const slot_base& src)
 {
   if (src.rep_ == rep_)
@@ -146,25 +178,7 @@ slot_base& slot_base::operator=(const slot_base& src)
 
   if (src.empty())
   {
-    if (rep_)
-    {
-      // Make sure we are notified if disconnect() deletes rep_, which is trackable.
-      // Compare slot_rep::notify().
-      destroy_notify_struct notifier;
-      rep_->add_destroy_notify_callback(&notifier, destroy_notify_struct::notify);
-      rep_->disconnect(); // Disconnect the slot (might lead to deletion of rep_!).
-
-      // If rep_ has been deleted, don't try to delete it again.
-      // If it has been deleted, this slot_base has probably also been deleted, so
-      // don't clear the rep_ pointer. It's the responsibility of the code that
-      // deletes rep_ to either clear the rep_ pointer or delete this slot_base.
-      if (!notifier.deleted_)
-      {
-        rep_->remove_destroy_notify_callback(&notifier);
-        delete rep_; // Detach the stored functor from the other referred trackables and destroy it.
-        rep_ = nullptr;
-      }
-    }
+    delete_rep_with_check();
 
     return *this;
   }
@@ -183,6 +197,23 @@ slot_base& slot_base::operator=(const slot_base& src)
   return *this;
 }
 
+slot_base& slot_base::operator=(slot_base&& src) noexcept
+{
+  if (src.rep_ == rep_)
+    return *this;
+ 
+  delete_rep_with_check();
+
+  rep_ = std::move(src.rep_);
+  blocked_ = std::move(src.blocked_);
+
+  //Wipe src:
+  src.rep_ = nullptr;
+  src.blocked_ = false;
+
+  return *this;
+}
+
 void slot_base::set_parent(void* parent, void* (*cleanup)(void*)) const
 {
   if (rep_)
diff --git a/sigc++/functors/slot_base.h b/sigc++/functors/slot_base.h
index 23763f6..3185c60 100644
--- a/sigc++/functors/slot_base.h
+++ b/sigc++/functors/slot_base.h
@@ -250,6 +250,8 @@ public:
    */
   slot_base(const slot_base& src);
 
+  slot_base(slot_base&& src) noexcept;
+
   ~slot_base();
 
   /** Tests whether a slot is null, because the default constructor was used.
@@ -325,12 +327,17 @@ public:
    */
   slot_base& operator=(const slot_base& src);
 
+  slot_base& operator=(slot_base&& src) noexcept;
+
 public: // public to avoid template friend declarations
   /** Typed slot_rep object that contains a functor. */
   mutable rep_type *rep_;
 
   /** Indicates whether the slot is blocked. */
   bool blocked_;
+
+private:
+  void delete_rep_with_check();
 };
 
 } //namespace sigc


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]