]> git.tdb.fi Git - ext/sigc++-2.0.git/blob - sigc++/adaptors/macros/compose.h.m4
Import libsigc++ 2.10.8 sources
[ext/sigc++-2.0.git] / sigc++ / adaptors / macros / compose.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([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)));
27     }
28
29 ])
30
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)));
38     }
39
40 ])
41
42 divert(0)
43 _FIREWALL([ADAPTORS_COMPOSE])
44 #include <sigc++/adaptors/adaptor_trait.h>
45
46 namespace sigc {
47
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.
52  *
53  * @par Examples:
54  * @code
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))
59  * @endcode
60  *
61  * The functor sigc::compose() returns can be passed directly into
62  * sigc::signal::connect().
63  *
64  * @par Example:
65  * @code
66  * sigc::signal<float,float,float> some_signal;
67  * some_signal.connect(sigc::compose(&square_root, &sum));
68  * @endcode
69  *
70  * @ingroup adaptors
71  */
72
73 /** Adaptor that combines two functors.
74  * Use the convenience function sigc::compose() to create an instance of sigc::compose1_functor.
75  *
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.
79  *
80  * @ingroup compose
81  */
82 template <class T_setter, class T_getter>
83 struct compose1_functor : public adapts<T_setter>
84 {
85   typedef typename adapts<T_setter>::adaptor_type adaptor_type;
86   typedef T_setter setter_type;
87   typedef T_getter getter_type;
88
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))>
94           >::type type; };
95 #endif
96   typedef typename adaptor_type::result_type  result_type;
97
98   result_type
99   operator()();
100
101 FOR(1,CALL_SIZE, [[COMPOSE1_OPERATOR(%1)]])dnl
102
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()().
106    */
107   compose1_functor(const T_setter& _A_setter, const T_getter& _A_getter)
108     : adapts<T_setter>(_A_setter), get_(_A_getter)
109     {}
110
111   getter_type get_; // public, so that visit_each() can access it
112 };
113
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_()); }
118
119 /** Adaptor that combines three functors.
120  * Use the convenience function sigc::compose() to create an instance of sigc::compose2_functor.
121  *
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.
126  *
127  * @ingroup compose
128  */
129 template <class T_setter, class T_getter1, class T_getter2>
130 struct compose2_functor : public adapts<T_setter>
131 {
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;
136
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; };
144 #endif
145   typedef typename adaptor_type::result_type  result_type;
146
147   result_type
148   operator()();
149
150 FOR(1,CALL_SIZE,[[COMPOSE2_OPERATOR(%1)]])dnl
151
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()().
156    */
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)
161     {}
162
163   getter1_type get1_; // public, so that visit_each() can access it
164   getter2_type get2_; // public, so that visit_each() can access it
165 };
166
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_()); }
171
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.
177  *
178  * @ingroup compose
179  */
180 template <class T_setter, class T_getter>
181 struct visitor<compose1_functor<T_setter, T_getter> >
182 {
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)
186   {
187     sigc::visit_each(_A_action, _A_target.functor_);
188     sigc::visit_each(_A_action, _A_target.get_);
189   }
190 };
191
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.
196  *
197  * @ingroup compose
198  */
199 template <class T_setter, class T_getter1, class T_getter2>
200 struct visitor<compose2_functor<T_setter, T_getter1, T_getter2> >
201 {
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)
205   {
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_);
209   }
210 };
211 #endif // DOXYGEN_SHOULD_SKIP_THIS
212
213 /** Creates an adaptor of type sigc::compose1_functor which combines two functors.
214  *
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.
218  *
219  * @ingroup compose
220  */
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); }
225
226 /** Creates an adaptor of type sigc::compose2_functor which combines three functors.
227  *
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.
232  *
233  * @ingroup compose
234  */
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); }
239
240 } /* namespace sigc */