1 dnl Copyright 2002, The libsigc++ Development Team
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.
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.
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
19 include(template.macros.m4)
22 $1[]ifelse($1,1,[st],$1,2,[nd],$1,3,[rd],[th])[]dnl
24 define([DEDUCE_RESULT_TYPE_COUNT],[dnl
25 template <LOOP(class T_arg%1, eval(CALL_SIZE))>
26 struct deduce_result_type_internal<LIST($2, LOOP(T_arg%1,eval(CALL_SIZE)))>
27 { typedef typename adaptor_type::template deduce_result_type<LIST(LOOP(_P_(T_arg%1), eval(CALL_SIZE-$2)), LOOP(_P_(typename unwrap_reference<T_type%1>::type), $1))>::type type; };
29 define([BIND_OPERATOR_LOCATION],[dnl
31 /** Invokes the wrapped functor passing on the arguments.
32 * bound_ is passed as the ORDINAL($1) argument.dnl
34 * @param _A_arg%1 Argument to be passed on to the functor.])
35 * @return The return value of the functor invocation.
37 template <LOOP([class T_arg%1], eval($2-1))>
38 typename deduce_result_type<LOOP(T_arg%1,eval($2-1))>::type
39 operator()(LOOP(T_arg%1 _A_arg%1,eval($2-1)))
40 { return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LIST(LOOP([_P_(T_arg%1)],eval($1-1)), _P_(typename unwrap_reference<T_bound>::type), FOR($1,eval($2-1),[_P_(T_arg%1),]))>
41 (LIST(LOOP(_A_arg%1,eval($1-1)), bound_.invoke(), FOR($1,eval($2-1),[_A_arg%1,])));
44 #ifndef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
45 template <LOOP([class T_arg%1], eval($2-1))>
46 typename deduce_result_type<LOOP(T_arg%1,eval($2-1))>::type
47 sun_forte_workaround(LOOP(T_arg%1 _A_arg%1,eval($2-1)))
48 { return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LIST(LOOP([_P_(T_arg%1)],eval($1-1)), _P_(typename unwrap_reference<T_bound>::type), FOR($1,eval($2-1),[_P_(T_arg%1),]))>
49 (LIST(LOOP(_A_arg%1,eval($1-1)), bound_.invoke(), FOR($1,eval($2-1),[_A_arg%1,])));
55 define([BIND_OPERATOR_COUNT],[dnl
56 /** Invokes the wrapped functor passing on the arguments.
57 * The last $1 argument(s) are fixed.dnl
59 * @param _A_arg%1 Argument to be passed on to the functor.])
60 * @return The return value of the functor invocation.
62 template <LOOP([class T_arg%1], eval($2-1))>
63 typename deduce_result_type<LOOP(T_arg%1,eval($2-1))>::type
64 operator()(LOOP(T_arg%1 _A_arg%1, eval($2-1)))
65 { return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LIST(LOOP([_P_(T_arg%1)],eval($2-1)), LOOP(_P_(typename unwrap_reference<T_type%1>::type), $1))>
66 (LIST(LOOP(_A_arg%1,eval($2-1)), LOOP(bound%1_.invoke(), $1)));
69 #ifndef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
70 template <LOOP([class T_arg%1], eval($2-1))>
71 typename deduce_result_type<LOOP(T_arg%1,eval($2-1))>::type
72 sun_forte_workaround(LOOP(T_arg%1 _A_arg%1, eval($2-1)))
73 { return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LIST(LOOP([_P_(T_arg%1)],eval($2-1)), LOOP(_P_(typename unwrap_reference<T_type%1>::type), $1))>
74 (LIST(LOOP(_A_arg%1,eval($2-1)), LOOP(bound%1_.invoke(), $1)));
79 define([BIND_FUNCTOR_LOCATION],[dnl
80 ifelse($1,1,[#ifndef DOXYGEN_SHOULD_SKIP_THIS
81 ],)dnl Include only the first template specialization in the documentation. ($1 = 0..CALL_SIZE-1)
82 /** Adaptor that binds an argument to the wrapped functor.
83 * This template specialization fixes the ORDINAL(eval($1+1)) argument of the wrapped functor.
87 template <class T_functor, class T_bound>
88 struct bind_functor<$1, T_functor, T_bound, LIST(LOOP(nil, CALL_SIZE - 1))> : public adapts<T_functor>
90 typedef typename adapts<T_functor>::adaptor_type adaptor_type;
92 ifelse($1,0,[#ifndef DOXYGEN_SHOULD_SKIP_THIS
94 template <LOOP(class T_arg%1=void, eval(CALL_SIZE))>
95 struct deduce_result_type
96 { typedef typename adaptor_type::template deduce_result_type<LIST(LOOP(_P_(T_arg%1),eval($1)), _P_(typename unwrap_reference<T_bound>::type), FOR(eval($1+1),eval(CALL_SIZE-1),[_P_(T_arg%1),]))>::type type; };
99 typedef typename adaptor_type::result_type result_type;
101 /** Invokes the wrapped functor passing on the bound argument only.
102 * @return The return value of the functor invocation.
107 //Note: The AIX compiler sometimes gives linker errors if we do not define this in the class.
108 return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<_P_(typename unwrap_reference<T_bound>::type)> (bound_.invoke());
111 FOR(eval($1+1),CALL_SIZE,[[BIND_OPERATOR_LOCATION(eval($1+1),%1)]])dnl
112 /** Constructs a bind_functor object that binds an argument to the passed functor.
113 * @param _A_func Functor to invoke from operator()().
114 * @param _A_bound Argument to bind to the functor.
116 bind_functor(_R_(T_functor) _A_func, _R_(T_bound) _A_bound)
117 : adapts<T_functor>(_A_func), bound_(_A_bound)
120 /// The argument bound to the functor.
121 bound_argument<T_bound> bound_;
123 ifelse($1,eval(CALL_SIZE-1),[#endif // DOXYGEN_SHOULD_SKIP_THIS
124 ],)dnl Include only the first template specialization in the documentation. ($1 = 0..CALL_SIZE-1)
126 ])dnl end BIND_FUNCTOR_LOCATION
128 define([BIND_FUNCTOR_COUNT],[dnl
129 /** Adaptor that binds $1 argument(s) to the wrapped functor.
130 * This template specialization fixes the last $1 argument(s) of the wrapped functor.
134 template <LIST(class T_functor, LOOP(class T_type%1, $1))>
135 struct bind_functor<LIST(-1, T_functor, LIST(LOOP(T_type%1, $1), LOOP(nil, CALL_SIZE - $1)))> : public adapts<T_functor>
137 typedef typename adapts<T_functor>::adaptor_type adaptor_type;
139 ifelse($1,1,[#ifndef DOXYGEN_SHOULD_SKIP_THIS
141 template <LIST(int count, LOOP(class T_arg%1, eval(CALL_SIZE)))>
142 struct deduce_result_type_internal
143 { typedef typename adaptor_type::template deduce_result_type<LIST(LOOP(_P_(T_arg%1), eval(CALL_SIZE-$1)), LOOP(_P_(typename unwrap_reference<T_type%1>::type), $1))>::type type; };
144 FOR(eval($1+1),eval(CALL_SIZE-1),[[DEDUCE_RESULT_TYPE_COUNT($1,%1)]])dnl
146 template <LOOP(class T_arg%1=void, eval(CALL_SIZE))>
147 struct deduce_result_type {
148 typedef typename deduce_result_type_internal<internal::count_void<LOOP(T_arg%1, eval(CALL_SIZE))>::value,
149 LOOP(T_arg%1, eval(CALL_SIZE))>::type type;
151 ifelse($1,1,[#endif // DOXYGEN_SHOULD_SKIP_THIS
153 typedef typename adaptor_type::result_type result_type;
155 /** Invokes the wrapped functor passing on the bound argument only.
156 * @return The return value of the functor invocation.
161 //Note: The AIX compiler sometimes gives linker errors if we do not define this in the class.
162 return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP(_P_(typename unwrap_reference<T_type%1>::type), $1)> (LOOP(bound%1_.invoke(), $1));
165 FOR(2,eval(CALL_SIZE-$1+1),[[BIND_OPERATOR_COUNT($1,%1)]])dnl
166 /** Constructs a bind_functor object that binds an argument to the passed functor.
167 * @param _A_func Functor to invoke from operator()().dnl
169 * @param _A_bound%1 Argument to bind to the functor.])
171 bind_functor(_R_(T_functor) _A_func, LOOP(_R_(T_type%1) _A_bound%1, $1))
172 : adapts<T_functor>(_A_func), LOOP(bound%1_(_A_bound%1), $1)
175 /// The argument bound to the functor.dnl
177 bound_argument<T_type%1> bound%1_;])
180 ifelse($1,1,[#ifndef DOXYGEN_SHOULD_SKIP_THIS
181 ],)dnl Include only the first template specialization of bind_functor and no
182 dnl template specialization of visitor in the documentation. ($1 = 1..CALL_SIZE)
183 //template specialization of visitor<>::do_visit_each<>(action, functor):
184 /** Performs a functor on each of the targets of a functor.
185 * The function overload for sigc::bind_functor performs a functor on the
186 * functor and on the object instances stored in the sigc::bind_functor object.
190 template <class T_functor, LOOP(class T_type%1, $1)>
191 struct visitor<bind_functor<-1, T_functor, LOOP(T_type%1, $1)> >
193 template <typename T_action>
194 static void do_visit_each(const T_action& _A_action,
195 const bind_functor<-1, T_functor, LOOP(T_type%1, $1)>& _A_target)
197 sigc::visit_each(_A_action, _A_target.functor_);dnl
199 sigc::visit_each(_A_action, _A_target.bound%1_);])
202 ifelse($1,CALL_SIZE,[#endif // DOXYGEN_SHOULD_SKIP_THIS
205 ])dnl end BIND_FUNCTOR_COUNT
207 define([BIND_COUNT],[dnl
208 /** Creates an adaptor of type sigc::bind_functor which fixes the last $1 argument(s) of the passed functor.
209 * This function overload fixes the last $1 argument(s) of @e _A_func.
211 * @param _A_func Functor that should be wrapped.dnl
213 * @param _A_b%1 Argument to bind to @e _A_func.])
214 * @return Adaptor that executes _A_func with the bound argument on invokation.
218 template <LIST(LOOP(class T_type%1, $1), class T_functor)>
219 inline bind_functor<-1, T_functor,dnl
223 bind(const T_functor& _A_func, LOOP(T_type%1 _A_b%1, $1))
224 { return bind_functor<-1, T_functor,dnl
228 (_A_func, LOOP(_A_b%1, $1));
234 _FIREWALL([ADAPTORS_BIND])
235 #include <sigc++/adaptors/adaptor_trait.h>
236 #include <sigc++/adaptors/bound_argument.h>
238 //TODO: See comment in functor_trait.h.
239 #if defined(nil) && defined(SIGC_PRAGMA_PUSH_POP_MACRO)
240 #define SIGC_NIL_HAS_BEEN_PUSHED 1
241 #pragma push_macro("nil")
247 #ifndef DOXYGEN_SHOULD_SKIP_THIS
251 template <class T_arg1,class T_arg2,class T_arg3,class T_arg4,class T_arg5,class T_arg6,class T_arg7>
253 { static const int value=0; };
254 template <class T_arg1,class T_arg2,class T_arg3,class T_arg4,class T_arg5,class T_arg6>
255 struct count_void<T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6,void>
256 { static const int value=1; };
257 template <class T_arg1,class T_arg2,class T_arg3,class T_arg4,class T_arg5>
258 struct count_void<T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,void,void>
259 { static const int value=2; };
260 template <class T_arg1,class T_arg2,class T_arg3,class T_arg4>
261 struct count_void<T_arg1,T_arg2,T_arg3,T_arg4,void,void,void>
262 { static const int value=3; };
263 template <class T_arg1,class T_arg2,class T_arg3>
264 struct count_void<T_arg1,T_arg2,T_arg3,void,void,void,void>
265 { static const int value=4; };
266 template <class T_arg1,class T_arg2>
267 struct count_void<T_arg1,T_arg2,void,void,void,void,void>
268 { static const int value=5; };
269 template <class T_arg1>
270 struct count_void<T_arg1,void,void,void,void,void,void>
271 { static const int value=6; };
273 struct count_void<void,void,void,void,void,void,void>
274 { static const int value=7; };
276 } /* namespace internal */
278 #endif /*DOXYGEN_SHOULD_SKIP_THIS*/
281 /** @defgroup bind bind(), bind_return()
282 * sigc::bind() alters an arbitrary functor by fixing arguments to certain values.
283 * Up to CALL_SIZE arguments can be bound at a time.
284 * For single argument binding, overloads of sigc::bind() are provided that let you
285 * specify the zero-based position of the argument to fix with the first template parameter.
286 * (A value of @p -1 fixes the last argument so sigc::bind<-1>() gives the same result as sigc::bind().)
287 * The types of the arguments can optionally be specified if not deduced.
291 * void foo(int, int, int);
292 * // single argument binding ...
293 * sigc::bind(&foo,1)(2,3); //fixes the last (third) argument and calls foo(2,3,1)
294 * sigc::bind<-1>(&foo,1)(2,3); //same as bind(&foo,1)(2,3) (calls foo(2,3,1))
295 * sigc::bind<0>(&foo,1)(2,3); //fixes the first argument and calls foo(1,2,3)
296 * sigc::bind<1>(&foo,1)(2,3); //fixes the second argument and calls foo(2,1,3)
297 * sigc::bind<2>(&foo,1)(2,3); //fixes the third argument and calls foo(2,3,1)
298 * // multi argument binding ...
299 * sigc::bind(&foo,1,2)(3); //fixes the last two arguments and calls foo(3,1,2)
300 * sigc::bind(&foo,1,2,3)(); //fixes all three arguments and calls foo(1,2,3)
303 * The functor sigc::bind() returns can be passed into
304 * sigc::signal::connect() directly.
308 * sigc::signal<void> some_signal;
310 * some_signal.connect(sigc::bind(&foo,1));
313 * sigc::bind_return() alters an arbitrary functor by
314 * fixing its return value to a certain value.
319 * std::cout << sigc::bind_return(&foo, 5)(); // calls foo() and returns 5
322 * You can bind references to functors by passing the objects through
323 * the std::ref() or std::cref() functions.
328 * sigc::signal<void> some_signal;
330 * some_signal.connect(sigc::bind(&foo, std::ref(some_int)));
333 * If you bind an object of a sigc::trackable derived type to a functor
334 * by reference, a slot assigned to the bind adaptor is cleared automatically
335 * when the object goes out of scope.
339 * struct bar : public sigc::trackable {} some_bar;
340 * sigc::signal<void> some_signal;
342 * some_signal.connect(sigc::bind(&foo, std::ref(some_bar)));
343 * // disconnected automatically if some_bar goes out of scope
349 /** Adaptor that binds an argument to the wrapped functor.
350 * Use the convenience function sigc::bind() to create an instance of sigc::bind_functor.
352 * The following template arguments are used:
353 * - @e I_location Zero-based position of the argument to fix (@p -1 for the last argument).dnl
355 * - @e T_type%1 Type of the [ORDINAL(%1)] bound argument.])
356 * - @e T_functor Type of the functor to wrap.
360 template <LIST(int I_location, class T_functor, LOOP(class T_type%1=nil, CALL_SIZE))>
361 #ifndef DOXYGEN_SHOULD_SKIP_THIS
364 struct bind_functor {};
367 FOR(0,eval(CALL_SIZE-1),[[BIND_FUNCTOR_LOCATION(%1)]])dnl
369 #ifndef DOXYGEN_SHOULD_SKIP_THIS
370 //template specialization of visitor<>::do_visit_each<>(action, functor):
371 /** Performs a functor on each of the targets of a functor.
372 * The function overload for sigc::bind_functor performs a functor on the
373 * functor and on the object instances stored in the sigc::bind_functor object.
377 template <int T_loc, class T_functor, class T_bound>
378 struct visitor<bind_functor<T_loc, T_functor, T_bound> >
380 template <class T_action>
381 static void do_visit_each(const T_action& _A_action,
382 const bind_functor<T_loc, T_functor, T_bound>& _A_target)
384 sigc::visit_each(_A_action, _A_target.functor_);
385 sigc::visit_each(_A_action, _A_target.bound_);
388 #endif // DOXYGEN_SHOULD_SKIP_THIS
390 FOR(1,CALL_SIZE,[[BIND_FUNCTOR_COUNT(%1)]])dnl
392 /** Creates an adaptor of type sigc::bind_functor which binds the passed argument to the passed functor.
393 * The optional template argument @e I_location specifies the zero-based
394 * position of the argument to be fixed (@p -1 stands for the last argument).
396 * @param _A_func Functor that should be wrapped.
397 * @param _A_b1 Argument to bind to @e _A_func.
398 * @return Adaptor that executes @e _A_func with the bound argument on invokation.
402 template <int I_location, class T_bound1, class T_functor>
403 inline bind_functor<I_location, T_functor, T_bound1>
404 bind(const T_functor& _A_func, T_bound1 _A_b1)
406 return bind_functor<I_location, T_functor, T_bound1>
410 FOR(1,CALL_SIZE,[[BIND_COUNT(%1)]])dnl
412 } /* namespace sigc */
414 #ifdef SIGC_NIL_HAS_BEEN_PUSHED
415 #undef SIGC_NIL_HAS_BEEN_PUSHED
416 #pragma pop_macro("nil")