]> git.tdb.fi Git - ext/sigc++-2.0.git/blob - sigc++/macros/limit_reference.h.m4
Import libsigc++ 2.10.8 sources
[ext/sigc++-2.0.git] / sigc++ / macros / limit_reference.h.m4
1 dnl Copyright 2002, The libsigc++ Development Team
2 dnl
3 dnl This library is free software; you can redistribute it and/or
4 dnl modify it under the terms of the GNU Lesser General Public
5 dnl License as published by the Free Software Foundation; either
6 dnl version 2.1 of the License, or (at your option) any later version.
7 dnl
8 dnl This library is distributed in the hope that it will be useful,
9 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
10 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 dnl Lesser General Public License for more details.
12 dnl
13 dnl You should have received a copy of the GNU Lesser General Public
14 dnl License along with this library; if not, write to the Free Software
15 dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 dnl
17 divert(-1)
18
19 include(template.macros.m4)
20
21 define([LIMIT_REFERENCE],[dnl
22 /** A [$1]limit_reference<Foo> object stores a reference (Foo&), but make sure that,
23  * if Foo inherits from sigc::trackable, then visit_each<>() will "limit" itself to the
24  * sigc::trackable reference instead of the derived reference. This avoids use of
25  * a reference to the derived type when the derived destructor has run. That can be
26  * a problem when using virtual inheritance.
27  *
28  * If Foo inherits from trackable then both the derived reference and the
29  * sigc::trackable reference are stored, so we can later retrieve the sigc::trackable
30  * reference without doing an implicit conversion. To retrieve the derived reference
31  * (so that you invoke methods or members of it), use invoke(). To retrieve the trackable
32  * reference (so that you can call visit_each() on it), you use visit().
33  *
34  * If Foo does not inherit from sigc::trackable then invoke() and visit() just return the
35  * derived reference.
36  *
37  * This is used for bound (sigc::bind) slot parameters (via bound_argument), bound return values,
38  * and, with mem_fun(), the reference to the handling object.
39  *
40  * - @e T_type The type of the reference.
41  */
42 template <class T_type,
43           bool I_derives_trackable =
44             std::is_base_of<trackable, T_type>::value>
45 class [$1]limit_reference
46 {
47 public:
48   /** Constructor.
49    * @param _A_target The reference to limit.
50    */
51   [$1]limit_reference([$2]T_type& _A_target)
52     : visited(_A_target)
53     {}
54
55   /** Retrieve the entity to visit for visit_each().
56    * Depending on the template specialization, this is either a derived reference, or sigc::trackable& if T_type derives from sigc::trackable.
57    * @return The reference.
58    */
59   inline const T_type& visit() const
60     { return visited; }
61
62   /** Retrieve the reference.
63    * This is always a reference to the derived instance.
64    * @return The reference.
65    */
66   inline [$3]T_type& invoke() const
67     { return visited; }
68
69 private:
70   /** The reference.
71    */
72   [$2]T_type& visited;
73 };
74
75 /** [$1]limit_reference object for a class that derives from trackable.
76  * - @e T_type The type of the reference.
77  */
78 template <class T_type>
79 class [$1]limit_reference<T_type, true>
80 {
81 public:
82   /** Constructor.
83    * @param _A_target The reference to limit.
84    */
85   [$1]limit_reference([$2]T_type& _A_target)
86     : visited(_A_target),
87       invoked(_A_target)
88     {}
89
90   /** Retrieve the entity to visit for visit_each().
91    * Depending on the template specialization, this is either a derived reference, or sigc::trackable& if T_type derives from sigc::trackable.
92    * @return The reference.
93    */
94   inline const trackable& visit() const
95     { return visited; }
96
97   /** Retrieve the reference.
98    * This is always a reference to the derived instance.
99    * @return The reference.
100    */
101   inline [$3]T_type& invoke() const
102     { return invoked; }
103
104 private:
105   /** The trackable reference.
106    */
107   [$2]trackable& visited;
108
109   /** The reference.
110    */
111   [$2]T_type& invoked;
112 };
113
114 #ifndef DOXYGEN_SHOULD_SKIP_THIS
115 /** Implementation of visitor specialized for the [$1]limit_reference
116  * class, to call visit_each() on the entity returned by the [$1]limit_reference's
117  * visit() method.
118  * @tparam T_type The type of the reference.
119  * @tparam T_action The type of functor to invoke.
120  * @param _A_action The functor to invoke.
121  * @param _A_target The visited instance.
122  */
123 template <class T_type, bool I_derives_trackable>
124 struct visitor<[$1]limit_reference<T_type, I_derives_trackable> >
125 {
126   template <class T_action>
127   static void do_visit_each(const T_action& _A_action,
128                             const [$1]limit_reference<T_type, I_derives_trackable>& _A_target)
129   {
130     sigc::visit_each(_A_action, _A_target.visit());
131   }
132 };
133 #endif // DOXYGEN_SHOULD_SKIP_THIS
134 ])
135
136 divert(0)
137
138 _FIREWALL([LIMIT_REFERENCE])
139
140 #include <sigc++/visit_each.h>
141 #include <sigc++/type_traits.h>
142 #include <sigc++/trackable.h>
143
144 namespace sigc {
145
146 LIMIT_REFERENCE([],[],[])dnl
147
148
149 LIMIT_REFERENCE([const_],[const ],[const ])dnl
150
151
152 LIMIT_REFERENCE([volatile_],[],[volatile ])dnl
153
154
155 LIMIT_REFERENCE([const_volatile_],[const ],[const volatile ])dnl
156
157 } /* namespace sigc */
158