1 dnl Copyright 2013, The libsigc++ Development Team
3 dnl This file is part of libsigc++.
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.
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.
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/>.
20 include(template.macros.m4)
22 define([TRACK_OBJECT_OPERATOR],[dnl
23 /** Invokes the wrapped functor passing on the arguments.dnl
25 * @param _A_arg%1 Argument to be passed on to the functor.])
26 * @return The return value of the functor invocation.
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))
32 return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP([
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))
42 return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP([
48 ])dnl end TRACK_OBJECT_OPERATOR
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.
55 * @tparam T_functor The type of functor to wrap.dnl
57 * @tparam T_obj%1 The type of a trackable object.])
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>
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
71 * @param _A_obj%1 Trackable object.])
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)]) {}
76 #ifndef DOXYGEN_SHOULD_SKIP_THIS
78 // public, so that visit_each() can access it.dnl
80 const_limit_reference<T_obj%1> obj%1_;])
81 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
83 }; // end class track_obj_functor$1
85 ])dnl end TRACK_OBJECT_FUNCTOR
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.
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)> >
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)
105 sigc::visit_each(_A_action, _A_target.functor_);dnl
107 sigc::visit_each(_A_action, _A_target.obj%1_);])
111 ])dnl end TRACK_OBJECT_VISIT_EACH
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
117 * @param _A_obj%1 Trackable object.])
118 * @return Adaptor that executes _A_func() on invocation.
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))
128 return track_obj_functor$1<T_functor, LOOP(T_obj%1, $1)>
129 (_A_func, LOOP(_A_obj%1, $1));
132 ])dnl end TRACK_OBJECT
135 _FIREWALL([ADAPTORS_TRACK_OBJ])
136 #include <sigc++/adaptors/adaptor_trait.h>
137 #include <sigc++/limit_reference.h>
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.
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.
153 * struct bar : public sigc::trackable {};
154 * sigc::signal<void> some_signal;
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
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.
173 * @tparam T_functor The type of functor to wrap.
174 * @tparam T_obj1 The type of a trackable object.
180 template <typename T_functor, typename T_obj1>
181 class track_obj_functor1 : public adapts<T_functor>
184 typedef typename adapts<T_functor>::adaptor_type adaptor_type;
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; };
191 typedef typename adaptor_type::result_type result_type;
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.
198 track_obj_functor1(const T_functor& _A_func, const T_obj1& _A_obj1)
199 : adapts<T_functor>(_A_func), obj1_(_A_obj1) {}
201 /** Invokes the wrapped functor.
202 * @return The return value of the functor invocation.
204 result_type operator()()
205 { return this->functor_(); }
207 FOR(1,CALL_SIZE,[[TRACK_OBJECT_OPERATOR(%1)]])dnl
209 #ifndef DOXYGEN_SHOULD_SKIP_THIS
211 // public, so that visit_each() can access it.
212 const_limit_reference<T_obj1> obj1_;
213 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
215 }; // end class track_obj_functor1
217 FOR(2,CALL_SIZE,[[TRACK_OBJECT_FUNCTOR(%1)]])dnl
219 #ifndef DOXYGEN_SHOULD_SKIP_THIS
220 FOR(1,CALL_SIZE,[[TRACK_OBJECT_VISIT_EACH(%1)]])dnl
221 #endif // DOXYGEN_SHOULD_SKIP_THIS
223 FOR(1,CALL_SIZE,[[TRACK_OBJECT(%1)]])dnl
225 } /* namespace sigc */