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)
21 define([COMPOSE1_OPERATOR],[dnl
22 template <LOOP(class T_arg%1, $1)>
23 typename deduce_result_type<LOOP(T_arg%1, $1)>::type
24 operator()(LOOP(T_arg%1 _A_a%1, $1))
25 { return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<sigc::deduce_result_t<LIST(T_getter, LOOP(T_arg%1,$1))>>
26 (get_(LOOP(_A_a%1, $1)));
31 define([COMPOSE2_OPERATOR],[dnl
32 template <LOOP(class T_arg%1, $1)>
33 typename deduce_result_type<LOOP(T_arg%1, $1)>::type
34 operator()(LOOP(T_arg%1 _A_a%1, $1))
35 { return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<sigc::deduce_result_t<LIST(T_getter1, LOOP(T_arg%1,$1))>,
36 sigc::deduce_result_t<LIST(T_getter2, LOOP(T_arg%1,$1))>>
37 (get1_(LOOP(_A_a%1, $1)), get2_(LOOP(_A_a%1,$1)));
43 _FIREWALL([ADAPTORS_COMPOSE])
44 #include <sigc++/adaptors/adaptor_trait.h>
48 /** @defgroup compose compose()
49 * sigc::compose() combines two or three arbitrary functors.
50 * On invokation, parameters are passed on to one or two getter functor(s).
51 * The return value(s) are then passed on to the setter function.
55 * float square_root(float a) { return sqrtf(a); }
56 * float sum(float a, float b) { return a+b; }
57 * std::cout << sigc::compose(&square_root, &sum)(9, 16); // calls square_root(sum(3,6))
58 * std::cout << sigc::compose(&sum, &square_root, &square_root)(9); // calls sum(square_root(9), square_root(9))
61 * The functor sigc::compose() returns can be passed directly into
62 * sigc::signal::connect().
66 * sigc::signal<float,float,float> some_signal;
67 * some_signal.connect(sigc::compose(&square_root, &sum));
73 /** Adaptor that combines two functors.
74 * Use the convenience function sigc::compose() to create an instance of sigc::compose1_functor.
76 * The following template arguments are used:
77 * - @e T_setter Type of the setter functor to wrap.
78 * - @e T_getter Type of the getter functor to wrap.
82 template <class T_setter, class T_getter>
83 struct compose1_functor : public adapts<T_setter>
85 typedef typename adapts<T_setter>::adaptor_type adaptor_type;
86 typedef T_setter setter_type;
87 typedef T_getter getter_type;
89 #ifndef DOXYGEN_SHOULD_SKIP_THIS
90 template <LOOP(class T_arg%1 = void, CALL_SIZE)>
91 struct deduce_result_type
92 { typedef typename adaptor_type::template deduce_result_type<
93 sigc::deduce_result_t<LIST(T_getter, LOOP(T_arg%1,CALL_SIZE))>
96 typedef typename adaptor_type::result_type result_type;
101 FOR(1,CALL_SIZE, [[COMPOSE1_OPERATOR(%1)]])dnl
103 /** Constructs a compose1_functor object that combines the passed functors.
104 * @param _A_setter Functor that receives the return values of the invokation of @e _A_getter1 and @e _A_getter2.
105 * @param _A_getter Functor to invoke from operator()().
107 compose1_functor(const T_setter& _A_setter, const T_getter& _A_getter)
108 : adapts<T_setter>(_A_setter), get_(_A_getter)
111 getter_type get_; // public, so that visit_each() can access it
114 template <class T_setter, class T_getter>
115 typename compose1_functor<T_setter, T_getter>::result_type
116 compose1_functor<T_setter, T_getter>::operator()()
117 { return this->functor_(get_()); }
119 /** Adaptor that combines three functors.
120 * Use the convenience function sigc::compose() to create an instance of sigc::compose2_functor.
122 * The following template arguments are used:
123 * - @e T_setter Type of the setter functor to wrap.
124 * - @e T_getter1 Type of the first getter functor to wrap.
125 * - @e T_getter2 Type of the second getter functor to wrap.
129 template <class T_setter, class T_getter1, class T_getter2>
130 struct compose2_functor : public adapts<T_setter>
132 typedef typename adapts<T_setter>::adaptor_type adaptor_type;
133 typedef T_setter setter_type;
134 typedef T_getter1 getter1_type;
135 typedef T_getter2 getter2_type;
137 #ifndef DOXYGEN_SHOULD_SKIP_THIS
138 template <LOOP(class T_arg%1=void, CALL_SIZE)>
139 struct deduce_result_type
140 { typedef typename adaptor_type::template deduce_result_type<
141 typename sigc::deduce_result_t<LIST(T_getter1, LOOP(T_arg%1,CALL_SIZE))>,
142 typename sigc::deduce_result_t<LIST(T_getter2, LOOP(T_arg%1,CALL_SIZE))>
143 >::type result_type; };
145 typedef typename adaptor_type::result_type result_type;
150 FOR(1,CALL_SIZE,[[COMPOSE2_OPERATOR(%1)]])dnl
152 /** Constructs a compose2_functor object that combines the passed functors.
153 * @param _A_setter Functor that receives the return values of the invokation of @e _A_getter1 and @e _A_getter2.
154 * @param _A_getter1 Functor to invoke from operator()().
155 * @param _A_getter2 Functor to invoke from operator()().
157 compose2_functor(const T_setter& _A_setter,
158 const T_getter1& _A_getter1,
159 const T_getter2& _A_getter2)
160 : adapts<T_setter>(_A_setter), get1_(_A_getter1), get2_(_A_getter2)
163 getter1_type get1_; // public, so that visit_each() can access it
164 getter2_type get2_; // public, so that visit_each() can access it
167 template <class T_setter, class T_getter1, class T_getter2>
168 typename compose2_functor<T_setter, T_getter1, T_getter2>::result_type
169 compose2_functor<T_setter, T_getter1, T_getter2>::operator()()
170 { return this->functor_(get1_(), get2_()); }
172 #ifndef DOXYGEN_SHOULD_SKIP_THIS
173 //template specialization of visitor<>::do_visit_each<>(action, functor):
174 /** Performs a functor on each of the targets of a functor.
175 * The function overload for sigc::compose1_functor performs a functor on the
176 * functors stored in the sigc::compose1_functor object.
180 template <class T_setter, class T_getter>
181 struct visitor<compose1_functor<T_setter, T_getter> >
183 template <class T_action>
184 static void do_visit_each(const T_action& _A_action,
185 const compose1_functor<T_setter, T_getter>& _A_target)
187 sigc::visit_each(_A_action, _A_target.functor_);
188 sigc::visit_each(_A_action, _A_target.get_);
192 //template specialization of visitor<>::do_visit_each<>(action, functor):
193 /** Performs a functor on each of the targets of a functor.
194 * The function overload for sigc::compose2_functor performs a functor on the
195 * functors stored in the sigc::compose2_functor object.
199 template <class T_setter, class T_getter1, class T_getter2>
200 struct visitor<compose2_functor<T_setter, T_getter1, T_getter2> >
202 template <class T_action>
203 static void do_visit_each(const T_action& _A_action,
204 const compose2_functor<T_setter, T_getter1, T_getter2>& _A_target)
206 sigc::visit_each(_A_action, _A_target.functor_);
207 sigc::visit_each(_A_action, _A_target.get1_);
208 sigc::visit_each(_A_action, _A_target.get2_);
211 #endif // DOXYGEN_SHOULD_SKIP_THIS
213 /** Creates an adaptor of type sigc::compose1_functor which combines two functors.
215 * @param _A_setter Functor that receives the return value of the invokation of @e _A_getter.
216 * @param _A_getter Functor to invoke from operator()().
217 * @return Adaptor that executes @e _A_setter with the value returned from invokation of @e _A_getter.
221 template <class T_setter, class T_getter>
222 inline compose1_functor<T_setter, T_getter>
223 compose(const T_setter& _A_setter, const T_getter& _A_getter)
224 { return compose1_functor<T_setter, T_getter>(_A_setter, _A_getter); }
226 /** Creates an adaptor of type sigc::compose2_functor which combines three functors.
228 * @param _A_setter Functor that receives the return values of the invokation of @e _A_getter1 and @e _A_getter2.
229 * @param _A_getter1 Functor to invoke from operator()().
230 * @param _A_getter2 Functor to invoke from operator()().
231 * @return Adaptor that executes @e _A_setter with the values return from invokation of @e _A_getter1 and @e _A_getter2.
235 template <class T_setter, class T_getter1, class T_getter2>
236 inline compose2_functor<T_setter, T_getter1, T_getter2>
237 compose(const T_setter& _A_setter, const T_getter1& _A_getter1, const T_getter2& _A_getter2)
238 { return compose2_functor<T_setter, T_getter1, T_getter2>(_A_setter, _A_getter1, _A_getter2); }
240 } /* namespace sigc */