[libsigcplusplus/variadic_mem_fun3: 120/148] limit_reference.h.m4: Make *_limit_reference template aliases of a limit_reference_base.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsigcplusplus/variadic_mem_fun3: 120/148] limit_reference.h.m4: Make *_limit_reference template aliases of a limit_reference_base.
- Date: Mon, 7 Mar 2016 10:07:54 +0000 (UTC)
commit 53610843e1f716de5dc98c6a34837b90c3103591
Author: Murray Cumming <murrayc murrayc com>
Date: Fri Mar 4 14:43:49 2016 +0100
limit_reference.h.m4: Make *_limit_reference template aliases of a limit_reference_base.
And have just one visitor specialization, using the base class.
As for *_mem_functor. This avoids the repetition.
sigc++/macros/limit_reference.h.m4 | 74 ++++++++++++++++++++++++------------
1 files changed, 50 insertions(+), 24 deletions(-)
---
diff --git a/sigc++/macros/limit_reference.h.m4 b/sigc++/macros/limit_reference.h.m4
index 679a86c..c8feabd 100644
--- a/sigc++/macros/limit_reference.h.m4
+++ b/sigc++/macros/limit_reference.h.m4
@@ -39,16 +39,50 @@ define([LIMIT_REFERENCE],[dnl
*
* - @e T_type The type of the reference.
*/
-template <class T_type,
+template <class T_type>
+using [$1]limit_reference = limit_reference_base<[$2]T_type, [$3]T_type, [$2]trackable>;
+])
+
+divert(0)
+
+_FIREWALL([LIMIT_REFERENCE])
+
+#include <sigc++/visit_each.h>
+#include <sigc++/type_traits.h>
+#include <sigc++/trackable.h>
+
+namespace sigc {
+
+/** A limit_reference_base<Foo> object stores a reference (Foo&), but make sure that,
+ * if Foo inherits from sigc::trackable, then visit_each<>() will "limit" itself to the
+ * sigc::trackable reference instead of the derived reference. This avoids use of
+ * a reference to the derived type when the derived destructor has run. That can be
+ * a problem when using virtual inheritance.
+ *
+ * If Foo inherits from trackable then both the derived reference and the
+ * sigc::trackable reference are stored, so we can later retrieve the sigc::trackable
+ * reference without doing an implicit conversion. To retrieve the derived reference
+ * (so that you invoke methods or members of it), use invoke(). To retrieve the trackable
+ * reference (so that you can call visit_each() on it), you use visit().
+ *
+ * If Foo does not inherit from sigc::trackable then invoke() and visit() just return the
+ * derived reference.
+ *
+ * This is used for bound (sigc::bind) slot parameters (via bound_argument), bound return values,
+ * and, with mem_fun(), the reference to the handling object.
+ *
+ * - @e T_type The type of the reference.
+ */
+template <class T_type, class T_type_invoke_result, class T_trackable,
bool I_derives_trackable =
- std::is_base_of<trackable, T_type>::value>
-class [$1]limit_reference
+ std::is_base_of<trackable, std::decay_t<T_type>>::value>
+class limit_reference_base
{
public:
/** Constructor.
* @param _A_target The reference to limit.
*/
- [$1]limit_reference([$2]T_type& _A_target)
+ limit_reference_base(T_type& _A_target)
: visited(_A_target)
{}
@@ -63,26 +97,26 @@ public:
* This is always a reference to the derived instance.
* @return The reference.
*/
- inline [$3]T_type& invoke() const
+ inline T_type_invoke_result& invoke() const
{ return visited; }
private:
/** The reference.
*/
- [$2]T_type& visited;
+ T_type& visited;
};
-/** [$1]limit_reference object for a class that derives from trackable.
+/** limit_reference_base object for a class that derives from trackable.
* - @e T_type The type of the reference.
*/
-template <class T_type>
-class [$1]limit_reference<T_type, true>
+template <class T_type, class T_type_invoke_result, class T_trackable>
+class limit_reference_base<T_type, T_type_invoke_result, T_trackable, true>
{
public:
/** Constructor.
* @param _A_target The reference to limit.
*/
- [$1]limit_reference([$2]T_type& _A_target)
+ limit_reference_base(T_type& _A_target)
: visited(_A_target),
invoked(_A_target)
{}
@@ -98,17 +132,17 @@ public:
* This is always a reference to the derived instance.
* @return The reference.
*/
- inline [$3]T_type& invoke() const
+ inline T_type_invoke_result& invoke() const
{ return invoked; }
private:
/** The trackable reference.
*/
- [$2]trackable& visited;
+ T_trackable& visited;
/** The reference.
*/
- [$2]T_type& invoked;
+ T_type& invoked;
};
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -120,28 +154,20 @@ private:
* @param _A_action The functor to invoke.
* @param _A_target The visited instance.
*/
-template <class T_type, bool I_derives_trackable>
-struct visitor<[$1]limit_reference<T_type, I_derives_trackable> >
+template <class T_type, class T_type_invoke_result, class T_trackable>
+struct visitor<limit_reference_base<T_type, T_type_invoke_result, T_trackable> >
{
template <class T_action>
static void do_visit_each(const T_action& _A_action,
- const [$1]limit_reference<T_type, I_derives_trackable>& _A_target)
+ const limit_reference_base<T_type, T_type_invoke_result, T_trackable>& _A_target)
{
sigc::visit_each(_A_action, _A_target.visit());
}
};
#endif // DOXYGEN_SHOULD_SKIP_THIS
-])
-
-divert(0)
-_FIREWALL([LIMIT_REFERENCE])
-#include <sigc++/visit_each.h>
-#include <sigc++/type_traits.h>
-#include <sigc++/trackable.h>
-namespace sigc {
LIMIT_REFERENCE([],[],[])dnl
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]