[libsigcplusplus/variadic_mem_fun3: 96/148] Add and use notifiable base class instead of void*.



commit 71a557954264c724123dc40bfa256fa8e21e3e2a
Author: Murray Cumming <murrayc murrayc com>
Date:   Thu Mar 3 10:53:11 2016 +0100

    Add and use notifiable base class instead of void*.
    
    Use notifiable as the  base class for trackable, connection, signal_impl,
    self_and_iter and destroy_notify_struct.
    
    Use this notifiable* instead of void* for the destroy/notify callback data.
    This is a little more type-safe and self-documenting.
    Bug #302152

 sigc++/connection.cc         |    3 +--
 sigc++/connection.h          |    4 ++--
 sigc++/functors/slot.h       |    3 +--
 sigc++/functors/slot_base.cc |   14 ++++++--------
 sigc++/functors/slot_base.h  |   23 +++++++++++++----------
 sigc++/signal_base.cc        |    6 +++---
 sigc++/signal_base.h         |    4 ++--
 sigc++/trackable.cc          |    8 ++++----
 sigc++/trackable.h           |   25 +++++++++++++++++--------
 9 files changed, 49 insertions(+), 41 deletions(-)
---
diff --git a/sigc++/connection.cc b/sigc++/connection.cc
index 0d1d52e..79d1202 100644
--- a/sigc++/connection.cc
+++ b/sigc++/connection.cc
@@ -99,11 +99,10 @@ void connection::set_slot(slot_base* sl)
     slot_->add_destroy_notify_callback(this, &notify);
 }
 
-void* connection::notify(void* data)
+void connection::notify(notifiable* data)
 {
   auto self = reinterpret_cast<connection*>(data);
   self->slot_ = nullptr;
-  return nullptr;
 }
 
 } /* namespace sigc */
diff --git a/sigc++/connection.h b/sigc++/connection.h
index 81ad07a..f8a55e2 100644
--- a/sigc++/connection.h
+++ b/sigc++/connection.h
@@ -37,7 +37,7 @@ namespace sigc {
  *
  * @ingroup signal
  */
-struct SIGC_API connection
+struct SIGC_API connection : public notifiable
 {
   /** Constructs an empty connection object. */
   connection() noexcept;
@@ -113,7 +113,7 @@ struct SIGC_API connection
   /** Callback that is executed when the referred slot is destroyed.
    * @param data The connection object notified (@p this).
    */
-  static void* notify(void* data);
+  static void notify(notifiable* data);
 
 private:
   void set_slot(slot_base* sl);
diff --git a/sigc++/functors/slot.h b/sigc++/functors/slot.h
index 7a3713f..ea793c7 100644
--- a/sigc++/functors/slot.h
+++ b/sigc++/functors/slot.h
@@ -56,7 +56,7 @@ struct typed_slot_rep : public slot_rep
   /** Detaches the stored functor from the other referred trackables and destroys it.
    * This does not destroy the base slot_rep object.
    */
-  static void* destroy(void* data)
+  static void destroy(notifiable* data)
     {
       self* self_ = static_cast<self*>(reinterpret_cast<slot_rep*>(data));
       self_->call_ = nullptr;
@@ -67,7 +67,6 @@ struct typed_slot_rep : public slot_rep
        * a) from the parent itself (in which case disconnect() leads to a segfault) or
        * b) from a parentless slot (in which case disconnect() does nothing)
        */
-      return nullptr;
     }
 
   /** Makes a deep copy of the slot_rep object.
diff --git a/sigc++/functors/slot_base.cc b/sigc++/functors/slot_base.cc
index 1b8285a..a0c4f7d 100644
--- a/sigc++/functors/slot_base.cc
+++ b/sigc++/functors/slot_base.cc
@@ -23,15 +23,14 @@ namespace
 {
 // Used by slot_rep::notify() and slot_base::operator=(). They must be
 // notified, if the slot_rep is deleted when they call disconnect().
-struct destroy_notify_struct
+struct destroy_notify_struct : public sigc::notifiable
 {
   destroy_notify_struct() noexcept : deleted_(false) { }
 
-  static void* notify(void* data) noexcept
+  static void notify(notifiable* data) noexcept
   {
     auto self_ = reinterpret_cast<destroy_notify_struct*>(data);
     self_->deleted_ = true;
-    return nullptr;
   }
 
   bool deleted_;
@@ -74,7 +73,7 @@ void slot_rep::disconnect()
 }
 
 //static
-void* slot_rep::notify(void* data)
+void slot_rep::notify(notifiable* data)
 {
   auto self_ = reinterpret_cast<slot_rep*>(data);
 
@@ -91,7 +90,6 @@ void* slot_rep::notify(void* data)
     self_->destroy(); // Detach the stored functor from the other referred trackables and destroy it.
                       // destroy() might lead to deletion of self_. Bug #564005.
   }
-  return nullptr;
 }
 
 } // namespace internal
@@ -261,19 +259,19 @@ slot_base& slot_base::operator=(slot_base&& src)
   return *this;
 }
 
-void slot_base::set_parent(void* parent, void* (*cleanup)(void*)) const noexcept
+void slot_base::set_parent(notifiable* parent, notifiable::func_destroy_notify cleanup) const noexcept
 {
   if (rep_)
     rep_->set_parent(parent, cleanup);
 }
 
-void slot_base::add_destroy_notify_callback(void* data, func_destroy_notify func) const
+void slot_base::add_destroy_notify_callback(notifiable* data, func_destroy_notify func) const
 {
   if (rep_)
     rep_->add_destroy_notify_callback(data, func);
 }
 
-void slot_base::remove_destroy_notify_callback(void* data) const
+void slot_base::remove_destroy_notify_callback(notifiable* data) const
 {
   if (rep_)
     rep_->remove_destroy_notify_callback(data);
diff --git a/sigc++/functors/slot_base.h b/sigc++/functors/slot_base.h
index d969751..61c1d79 100644
--- a/sigc++/functors/slot_base.h
+++ b/sigc++/functors/slot_base.h
@@ -75,7 +75,7 @@ struct SIGC_API slot_rep : public trackable
   /* This could be a replaced by a virtual dtor. However since this struct is
    * crucual for the efficiency of the whole library we want to avoid this.
    */
-  hook destroy_;
+  func_destroy_notify destroy_;
 
   /** Callback that makes a deep copy of the slot_rep object.
    * @return A deep copy of the slot_rep object.
@@ -83,12 +83,12 @@ struct SIGC_API slot_rep : public trackable
   hook dup_;
 
   /** Callback of parent_. */
-  hook cleanup_;
+  func_destroy_notify cleanup_;
 
   /** Parent object whose callback cleanup_ is executed on notification. */
-  void* parent_;
+  notifiable* parent_;
 
-  inline slot_rep(hook call__, hook destroy__, hook dup__) noexcept
+  inline slot_rep(hook call__, notifiable::func_destroy_notify destroy__, hook dup__) noexcept
     : call_(call__), destroy_(destroy__), dup_(dup__), cleanup_(nullptr), parent_(nullptr) {}
 
   inline ~slot_rep()
@@ -116,7 +116,7 @@ struct SIGC_API slot_rep : public trackable
    * @param parent The new parent.
    * @param cleanup The callback to execute from notify().
    */
-  inline void set_parent(void* parent, hook cleanup) noexcept
+  inline void set_parent(notifiable* parent, notifiable::func_destroy_notify cleanup) noexcept
     {
       parent_ = parent;
       cleanup_ = cleanup;
@@ -132,7 +132,7 @@ struct SIGC_API slot_rep : public trackable
    * referred object dying.
    * @param data The slot_rep object that is becoming invalid (@p this).
    */
-  static void* notify(void* data);
+  static void notify(notifiable* data);
 };
 
 /** Functor used to add a dependency to a trackable.
@@ -284,6 +284,8 @@ public:
    */
   explicit operator bool() const noexcept;
 
+  typedef notifiable::func_destroy_notify func_destroy_notify;
+
   /** Sets the parent of this slot.
    * This function is used by signals to register a notification callback.
    * This notification callback is executed when the slot becomes invalid
@@ -291,21 +293,22 @@ public:
    * @param parent The new parent.
    * @param cleanup The notification callback.
    */
-  void set_parent(void* parent, void* (*cleanup)(void*)) const noexcept;
+  void set_parent(notifiable* parent, notifiable::func_destroy_notify cleanup) const noexcept;
+
+
 
-  typedef trackable::func_destroy_notify func_destroy_notify;
   /** Add a callback that is executed (notified) when the slot is detroyed.
    * This function is used internally by connection objects.
    * @param data Passed into func upon notification.
    * @param func Callback executed upon destruction of the object.
    */
-  void add_destroy_notify_callback(void* data, func_destroy_notify func) const;
+  void add_destroy_notify_callback(notifiable* data, notifiable::func_destroy_notify func) const;
 
   /** Remove a callback previously installed with add_destroy_notify_callback().
    * The callback is not executed.
    * @param data Parameter passed into previous call to add_destroy_notify_callback().
    */
-  void remove_destroy_notify_callback(void* data) const;
+  void remove_destroy_notify_callback(notifiable* data) const;
 
   /** Returns whether the slot is invalid.
    * @return @p true if the slot is invalid (empty).
diff --git a/sigc++/signal_base.cc b/sigc++/signal_base.cc
index cc8342b..bbb1955 100644
--- a/sigc++/signal_base.cc
+++ b/sigc++/signal_base.cc
@@ -24,7 +24,7 @@ namespace internal {
 // Data sent from signal_impl::insert() to slot_rep::set_parent() when a slot is
 // connected, and then sent from slot_rep::disconnect() to signal_impl::notify()
 // when the slot is disconnected. Bug 167714.
-struct self_and_iter
+struct self_and_iter : public notifiable
 {
   signal_impl* self_;
   signal_impl::iterator_type iter_;
@@ -149,7 +149,7 @@ void signal_impl::sweep()
 }
 
 //static
-void* signal_impl::notify(void* d)
+void signal_impl::notify(notifiable* d)
 {
   std::unique_ptr<self_and_iter> si(static_cast<self_and_iter*>(d));
 
@@ -163,7 +163,7 @@ void* signal_impl::notify(void* d)
   }
   else                           // This is occuring during signal emission or slot erasure.
     si->self_->deferred_ = true; // => sweep() will be called from ~signal_exec() after signal emission.
-  return nullptr;                // This is safer because we don't have to care about our
+                                 // This is safer because we don't have to care about our
                                  // iterators in emit(), clear(), and erase().
 }
 
diff --git a/sigc++/signal_base.h b/sigc++/signal_base.h
index f50a6cb..94037ca 100644
--- a/sigc++/signal_base.h
+++ b/sigc++/signal_base.h
@@ -42,7 +42,7 @@ namespace internal
  * erase() to sweep() when the signal is being emitted. sweep() removes all
  * invalid slots from the list.
  */
-struct SIGC_API signal_impl
+struct SIGC_API signal_impl : public notifiable
 {
   typedef std::size_t size_type;
   typedef std::list<slot_base> slot_list;
@@ -167,7 +167,7 @@ struct SIGC_API signal_impl
    * erase() to sweep() when the signal is being emitted.
    * @param d A local structure, created in insert().
    */
-  static void* notify(void* d);
+  static void notify(notifiable* d);
 
   /** Reference counter.
    * The object is destroyed when @em ref_count_ reaches zero.
diff --git a/sigc++/trackable.cc b/sigc++/trackable.cc
index 135d1ca..7c492ea 100644
--- a/sigc++/trackable.cc
+++ b/sigc++/trackable.cc
@@ -67,12 +67,12 @@ trackable::~trackable()
   notify_callbacks();
 }
 
-void trackable::add_destroy_notify_callback(void* data, func_destroy_notify func) const
+void trackable::add_destroy_notify_callback(notifiable* data, func_destroy_notify func) const
 {
   callback_list()->add_callback(data, func);
 }
 
-void trackable::remove_destroy_notify_callback(void* data) const
+void trackable::remove_destroy_notify_callback(notifiable* data) const
 {
   callback_list()->remove_callback(data);
 }
@@ -106,7 +106,7 @@ trackable_callback_list::~trackable_callback_list()
       callback.func_(callback.data_);
 }
 
-void trackable_callback_list::add_callback(void* data, func_destroy_notify func)
+void trackable_callback_list::add_callback(notifiable* data, func_destroy_notify func)
 {
   if (!clearing_)  // TODO: Is it okay to silently ignore attempts to add dependencies when the list is 
being cleared?
                    //       I'd consider this a serious application bug, since the app is likely to segfault.
@@ -127,7 +127,7 @@ void trackable_callback_list::clear()
   clearing_ = false;
 }
 
-void trackable_callback_list::remove_callback(void* data)
+void trackable_callback_list::remove_callback(notifiable* data)
 {
   for (callback_list::iterator i = callbacks_.begin(); i != callbacks_.end(); ++i)
   {
diff --git a/sigc++/trackable.h b/sigc++/trackable.h
index 6f9b017..f148785 100644
--- a/sigc++/trackable.h
+++ b/sigc++/trackable.h
@@ -23,9 +23,12 @@
 
 namespace sigc {
 
+struct notifiable;
+
 namespace internal {
 
-typedef void* (*func_destroy_notify) (void* data);
+typedef void (*func_destroy_notify) (notifiable* data);
+
 
 /** Destroy notification callback.
  * A destroy notification callback consists of a data pointer and a
@@ -35,9 +38,9 @@ typedef void* (*func_destroy_notify) (void* data);
  */
 struct SIGC_API trackable_callback
 {
-  void* data_;
+  notifiable* data_;
   func_destroy_notify func_;
-  trackable_callback(void* data, func_destroy_notify func) noexcept
+  trackable_callback(notifiable* data, func_destroy_notify func) noexcept
     : data_(data), func_(func) {}
 };
 
@@ -54,12 +57,12 @@ struct SIGC_API trackable_callback_list
    * @param func The callback function.
    * 
    */
-  void add_callback(void* data, func_destroy_notify func);
+  void add_callback(notifiable* data, func_destroy_notify func);
 
   /** Remove the callback which has this data associated with it.
    * @param data The data that was given as a parameter to add_callback().
    */
-  void remove_callback(void* data);
+  void remove_callback(notifiable* data);
 
   /** This invokes all of the callback functions.
    */
@@ -86,6 +89,12 @@ private:
 } /* namespace internal */
 
 
+struct SIGC_API notifiable
+{
+  typedef internal::func_destroy_notify func_destroy_notify;
+};
+
+
 /** Base class for objects with auto-disconnection.
  * trackable must be inherited when objects shall automatically
  * invalidate slots referring to them on destruction.
@@ -106,7 +115,7 @@ private:
  *
  * @ingroup signal
  */
-struct SIGC_API trackable
+struct SIGC_API trackable : public notifiable
 {
   // Concerning noexcept specifications:
   // libsigc++ does not have complete control of what happens when notify_callbacks()
@@ -135,13 +144,13 @@ struct SIGC_API trackable
    * @param data Passed into func upon notification.
    * @param func Callback executed upon destruction of the object.
    */
-  void add_destroy_notify_callback(void* data, func_destroy_notify func) const;
+  void add_destroy_notify_callback(notifiable* data, func_destroy_notify func) const;
 
   /** Remove a callback previously installed with add_destroy_notify_callback().
    * The callback is not executed.
    * @param data Parameter passed into previous call to add_destroy_notify_callback().
    */
-  void remove_destroy_notify_callback(void* data) const;
+  void remove_destroy_notify_callback(notifiable* data) const;
 
   /// Execute and remove all previously installed callbacks.
   void notify_callbacks();


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