]> git.tdb.fi Git - ext/sigc++-2.0.git/blob - sigc++/adaptors/macros/track_obj.h.m4
Import libsigc++ 2.10.8 sources
[ext/sigc++-2.0.git] / sigc++ / adaptors / macros / track_obj.h.m4
1 dnl Copyright 2013, The libsigc++ Development Team
2 dnl
3 dnl This file is part of libsigc++.
4 dnl
5 dnl This library is free software; you can redistribute it and/or
6 dnl modify it under the terms of the GNU Lesser General Public
7 dnl License as published by the Free Software Foundation; either
8 dnl version 2.1 of the License, or (at your option) any later version.
9 dnl
10 dnl This library is distributed in the hope that it will be useful,
11 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
12 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 dnl Lesser General Public License for more details.
14 dnl
15 dnl You should have received a copy of the GNU Lesser General Public
16 dnl License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 dnl
18 divert(-1)
19
20 include(template.macros.m4)
21
22 define([TRACK_OBJECT_OPERATOR],[dnl
23   /** Invokes the wrapped functor passing on the arguments.dnl
24 FOR(1, $1,[
25    * @param _A_arg%1 Argument to be passed on to the functor.])
26    * @return The return value of the functor invocation.
27    */
28   template <LOOP([typename T_arg%1], $1)>
29   typename deduce_result_type<LOOP(T_arg%1, $1)>::type
30   operator()(LOOP(T_arg%1 _A_arg%1, $1))
31   {
32     return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP([
33       _P_(T_arg%1)], $1)>
34       (LOOP(_A_arg%1, $1));
35   }
36
37   #ifndef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
38   template <LOOP([typename T_arg%1], $1)>
39   typename deduce_result_type<LOOP(T_arg%1, $1)>::type
40   sun_forte_workaround(LOOP(T_arg%1 _A_arg%1, $1))
41   {
42     return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP([
43       _P_(T_arg%1)], $1)>
44       (LOOP(_A_arg%1, $1));
45   }
46   #endif
47
48 ])dnl end TRACK_OBJECT_OPERATOR
49
50 dnl track_obj_functor[2..CALL_SIZE]. $1 is assumed to be >= 2.
51 define([TRACK_OBJECT_FUNCTOR],[dnl
52 /** track_obj_functor$1 wraps a functor and stores $1 references to trackable objects.
53  * Use the convenience function track_obj() to create an instance of track_obj_functor$1.
54  *
55  * @tparam T_functor The type of functor to wrap.dnl
56 FOR(1,$1,[
57  * @tparam T_obj%1 The type of a trackable object.])
58  *
59  * @newin{2,4}
60  *
61  * @ingroup track_obj
62  */
63 template <typename T_functor, LOOP(typename T_obj%1, $1)>
64 class track_obj_functor$1 : public track_obj_functor1<T_functor, T_obj1>
65 {
66 public:
67   /** Constructs a track_obj_functor$1 object that wraps the passed functor and
68    * stores references to the passed trackable objects.
69    * @param _A_func Functor.dnl
70 FOR(1,$1,[
71    * @param _A_obj%1 Trackable object.])
72    */
73   track_obj_functor$1(const T_functor& _A_func, LOOP(const T_obj%1& _A_obj%1, $1))
74   : track_obj_functor1<T_functor, T_obj1>(_A_func, _A_obj1)FOR(2,$1,[[, ]obj%1_(_A_obj%1)]) {}
75
76 #ifndef DOXYGEN_SHOULD_SKIP_THIS
77 //protected:
78   // public, so that visit_each() can access it.dnl
79 FOR(2,$1,[
80   const_limit_reference<T_obj%1> obj%1_;])
81 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
82
83 }; // end class track_obj_functor$1
84
85 ])dnl end TRACK_OBJECT_FUNCTOR
86
87 define([TRACK_OBJECT_VISIT_EACH],[dnl
88 //template specialization of visitor<>::do_visit_each<>(action, functor):
89 /** Performs a functor on each of the targets of a functor.
90  * The function overload for sigc::track_obj_functor$1 performs a functor
91  * on the functor and on the trackable object instances stored in the
92  * sigc::track_obj_functor$1 object.
93  *
94  * @newin{2,4}
95  *
96  * @ingroup track_obj
97  */
98 template <typename T_functor, LOOP(typename T_obj%1, $1)>
99 struct visitor<track_obj_functor$1<T_functor, LOOP(T_obj%1, $1)> >
100 {
101   template <typename T_action>
102   static void do_visit_each(const T_action& _A_action,
103                             const track_obj_functor$1<T_functor, LOOP(T_obj%1, $1)>& _A_target)
104   {
105     sigc::visit_each(_A_action, _A_target.functor_);dnl
106 FOR(1,$1,[
107     sigc::visit_each(_A_action, _A_target.obj%1_);])
108   }
109 };
110
111 ])dnl end TRACK_OBJECT_VISIT_EACH
112
113 define([TRACK_OBJECT],[dnl
114 /** Creates an adaptor of type sigc::track_obj_functor$1 which wraps a functor.
115  * @param _A_func Functor that shall be wrapped.dnl
116 FOR(1,$1,[
117  * @param _A_obj%1 Trackable object.])
118  * @return Adaptor that executes _A_func() on invocation.
119  *
120  * @newin{2,4}
121  *
122  * @ingroup track_obj
123  */
124 template <typename T_functor, LOOP(typename T_obj%1, $1)>
125 inline track_obj_functor$1<T_functor, LOOP(T_obj%1, $1)>
126 track_obj(const T_functor& _A_func, LOOP(const T_obj%1& _A_obj%1, $1))
127 {
128   return track_obj_functor$1<T_functor, LOOP(T_obj%1, $1)>
129     (_A_func, LOOP(_A_obj%1, $1));
130 }
131
132 ])dnl end TRACK_OBJECT
133
134 divert(0)dnl
135 _FIREWALL([ADAPTORS_TRACK_OBJ])
136 #include <sigc++/adaptors/adaptor_trait.h>
137 #include <sigc++/limit_reference.h>
138
139 namespace sigc {
140
141 /** @defgroup track_obj track_obj()
142  * sigc::track_obj() tracks trackable objects, referenced from a functor.
143  * It can be useful when you assign a C++11 lambda expression or a std::function<>
144  * to a slot, or connect it to a signal, and the lambda expression or std::function<>
145  * contains references to sigc::trackable derived objects.
146  *
147  * The functor returned by sigc::track_obj() is formally an adaptor, but it does
148  * not alter the signature, return type or behaviour of the supplied functor.
149  * Up to CALL_SIZE objects can be tracked. operator()() can have up to CALL_SIZE arguments.
150  *
151  * @par Example:
152  * @code
153  * struct bar : public sigc::trackable {};
154  * sigc::signal<void> some_signal;
155  * void foo(bar&);
156  * {
157  *   bar some_bar;
158  *   some_signal.connect([[&some_bar]](){ foo(some_bar); });
159  *     // NOT disconnected automatically when some_bar goes out of scope
160  *   some_signal.connect(sigc::track_obj([[&some_bar]](){ foo(some_bar); }, some_bar);
161  *     // disconnected automatically when some_bar goes out of scope
162  * }
163  * @endcode
164  *
165  * @newin{2,4}
166  *
167  * @ingroup adaptors
168  */
169
170 /** track_obj_functor1 wraps a functor and stores a reference to a trackable object.
171  * Use the convenience function track_obj() to create an instance of track_obj_functor1.
172  *
173  * @tparam T_functor The type of functor to wrap.
174  * @tparam T_obj1 The type of a trackable object.
175  *
176  * @newin{2,4}
177  *
178  * @ingroup track_obj
179  */
180 template <typename T_functor, typename T_obj1>
181 class track_obj_functor1 : public adapts<T_functor>
182 {
183 public:
184   typedef typename adapts<T_functor>::adaptor_type adaptor_type;
185
186 #ifndef DOXYGEN_SHOULD_SKIP_THIS
187   template <LOOP(typename T_arg%1=void, CALL_SIZE)>
188   struct deduce_result_type
189     { typedef typename adaptor_type::template deduce_result_type<LOOP(_P_(T_arg%1), CALL_SIZE)>::type type; };
190 #endif
191   typedef typename adaptor_type::result_type result_type;
192
193   /** Constructs a track_obj_functor1 object that wraps the passed functor and
194    * stores a reference to the passed trackable object.
195    * @param _A_func Functor.
196    * @param _A_obj1 Trackable object.
197    */
198   track_obj_functor1(const T_functor& _A_func, const T_obj1& _A_obj1)
199   : adapts<T_functor>(_A_func), obj1_(_A_obj1) {}
200
201   /** Invokes the wrapped functor.
202    * @return The return value of the functor invocation.
203    */
204   result_type operator()()
205   { return this->functor_(); }
206
207 FOR(1,CALL_SIZE,[[TRACK_OBJECT_OPERATOR(%1)]])dnl
208
209 #ifndef DOXYGEN_SHOULD_SKIP_THIS
210 //protected:
211   // public, so that visit_each() can access it.
212   const_limit_reference<T_obj1> obj1_;
213 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
214
215 }; // end class track_obj_functor1
216
217 FOR(2,CALL_SIZE,[[TRACK_OBJECT_FUNCTOR(%1)]])dnl
218
219 #ifndef DOXYGEN_SHOULD_SKIP_THIS
220 FOR(1,CALL_SIZE,[[TRACK_OBJECT_VISIT_EACH(%1)]])dnl
221 #endif // DOXYGEN_SHOULD_SKIP_THIS
222
223 FOR(1,CALL_SIZE,[[TRACK_OBJECT(%1)]])dnl
224
225 } /* namespace sigc */