Imported Upstream version 2.99.2
[platform/upstream/libsigc++.git] / sigc++ / adaptors / compose.h
1 #ifndef _SIGC_ADAPTORS_COMPOSE_H_
2 #define _SIGC_ADAPTORS_COMPOSE_H_
3 #include <sigc++/adaptors/adaptor_trait.h>
4
5 namespace sigc {
6
7 /** @defgroup compose compose()
8  * sigc::compose() combines two or three arbitrary functors.
9  * On invokation, parameters are passed on to one or two getter functor(s).
10  * The return value(s) are then passed on to the setter function.
11  *
12  * @par Examples:
13  * @code
14  * float square_root(float a)  { return sqrtf(a); }
15  * float sum(float a, float b) { return a+b; }
16  * std::cout << sigc::compose(&square_root, &sum)(9, 16); // calls square_root(sum(3,6))
17  * std::cout << sigc::compose(&sum, &square_root, &square_root)(9); // calls sum(square_root(9), square_root(9))
18  * @endcode
19  *
20  * The functor sigc::compose() returns can be passed directly into
21  * sigc::signal::connect().
22  *
23  * @par Example:
24  * @code
25  * sigc::signal(float(float, float)> some_signal;
26  * some_signal.connect(sigc::compose(&square_root, &sum));
27  * @endcode
28  *
29  * @ingroup adaptors
30  */
31
32 /** Adaptor that combines two functors.
33  * Use the convenience function sigc::compose() to create an instance of sigc::compose1_functor.
34  *
35  * The following template arguments are used:
36  * - @e T_setter Type of the setter functor to wrap.
37  * - @e T_getter Type of the getter functor to wrap.
38  *
39  * @ingroup compose
40  */
41 template <class T_setter, class T_getter>
42 struct compose1_functor : public adapts<T_setter>
43 {
44   using adaptor_type = typename adapts<T_setter>::adaptor_type;
45   using setter_type = T_setter;
46   using getter_type = T_getter;
47   using result_type = typename adaptor_type::result_type;
48
49   decltype(auto)
50   operator()()
51     { return this->functor_(get_()); }
52
53
54   template <class... T_arg>
55   decltype(auto)
56   operator()(T_arg&&... _A_a)
57     { return this->functor_(get_(std::forward<T_arg>(_A_a)...));
58     }
59
60   /** Constructs a compose1_functor object that combines the passed functors.
61    * @param _A_setter Functor that receives the return values of the invokation of @e _A_getter1 and @e _A_getter2.
62    * @param _A_getter Functor to invoke from operator()().
63    */
64   compose1_functor(const T_setter& _A_setter, const T_getter& _A_getter)
65     : adapts<T_setter>(_A_setter), get_(_A_getter)
66     {}
67
68   getter_type get_; // public, so that visit_each() can access it
69 };
70
71 /** Adaptor that combines three functors.
72  * Use the convenience function sigc::compose() to create an instance of sigc::compose2_functor.
73  *
74  * The following template arguments are used:
75  * - @e T_setter Type of the setter functor to wrap.
76  * - @e T_getter1 Type of the first getter functor to wrap.
77  * - @e T_getter2 Type of the second getter functor to wrap.
78  *
79  * @ingroup compose
80  */
81 template <class T_setter, class T_getter1, class T_getter2>
82 struct compose2_functor : public adapts<T_setter>
83 {
84   using adaptor_type = typename adapts<T_setter>::adaptor_type;
85   using setter_type = T_setter;
86   using getter1_type = T_getter1;
87   using getter2_type = T_getter2;
88   using result_type = typename adaptor_type::result_type;
89
90   decltype(auto)
91   operator()()
92     { return this->functor_(get1_(), get2_()); }
93
94
95   template <class... T_arg>
96   decltype(auto)
97   operator()(T_arg... _A_a)
98     { return this->functor_(get1_(_A_a...), get2_(_A_a...));
99     }
100
101   /** Constructs a compose2_functor object that combines the passed functors.
102    * @param _A_setter Functor that receives the return values of the invokation of @e _A_getter1 and @e _A_getter2.
103    * @param _A_getter1 Functor to invoke from operator()().
104    * @param _A_getter2 Functor to invoke from operator()().
105    */
106   compose2_functor(const T_setter& _A_setter,
107                    const T_getter1& _A_getter1,
108                    const T_getter2& _A_getter2)
109     : adapts<T_setter>(_A_setter), get1_(_A_getter1), get2_(_A_getter2)
110     {}
111
112   getter1_type get1_; // public, so that visit_each() can access it
113   getter2_type get2_; // public, so that visit_each() can access it
114 };
115
116 #ifndef DOXYGEN_SHOULD_SKIP_THIS
117 //template specialization of visitor<>::do_visit_each<>(action, functor):
118 /** Performs a functor on each of the targets of a functor.
119  * The function overload for sigc::compose1_functor performs a functor on the
120  * functors stored in the sigc::compose1_functor object.
121  *
122  * @ingroup compose
123  */
124 template <class T_setter, class T_getter>
125 struct visitor<compose1_functor<T_setter, T_getter> >
126 {
127   template <class T_action>
128   static void do_visit_each(const T_action& _A_action,
129                             const compose1_functor<T_setter, T_getter>& _A_target)
130   {
131     sigc::visit_each(_A_action, _A_target.functor_);
132     sigc::visit_each(_A_action, _A_target.get_);
133   }
134 };
135
136 //template specialization of visitor<>::do_visit_each<>(action, functor):
137 /** Performs a functor on each of the targets of a functor.
138  * The function overload for sigc::compose2_functor performs a functor on the
139  * functors stored in the sigc::compose2_functor object.
140  *
141  * @ingroup compose
142  */
143 template <class T_setter, class T_getter1, class T_getter2>
144 struct visitor<compose2_functor<T_setter, T_getter1, T_getter2> >
145 {
146   template <class T_action>
147   static void do_visit_each(const T_action& _A_action,
148                             const compose2_functor<T_setter, T_getter1, T_getter2>& _A_target)
149   {
150     sigc::visit_each(_A_action, _A_target.functor_);
151     sigc::visit_each(_A_action, _A_target.get1_);
152     sigc::visit_each(_A_action, _A_target.get2_);
153   }
154 };
155 #endif // DOXYGEN_SHOULD_SKIP_THIS
156
157 /** Creates an adaptor of type sigc::compose1_functor which combines two functors.
158  *
159  * @param _A_setter Functor that receives the return value of the invokation of @e _A_getter.
160  * @param _A_getter Functor to invoke from operator()().
161  * @return Adaptor that executes @e _A_setter with the value returned from invokation of @e _A_getter.
162  *
163  * @ingroup compose
164  */
165 template <class T_setter, class T_getter>
166 inline compose1_functor<T_setter, T_getter>
167 compose(const T_setter& _A_setter, const T_getter& _A_getter)
168   { return compose1_functor<T_setter, T_getter>(_A_setter, _A_getter); }
169
170 /** Creates an adaptor of type sigc::compose2_functor which combines three functors.
171  *
172  * @param _A_setter Functor that receives the return values of the invokation of @e _A_getter1 and @e _A_getter2.
173  * @param _A_getter1 Functor to invoke from operator()().
174  * @param _A_getter2 Functor to invoke from operator()().
175  * @return Adaptor that executes @e _A_setter with the values return from invokation of @e _A_getter1 and @e _A_getter2.
176  *
177  * @ingroup compose
178  */
179 template <class T_setter, class T_getter1, class T_getter2>
180 inline compose2_functor<T_setter, T_getter1, T_getter2>
181 compose(const T_setter& _A_setter, const T_getter1& _A_getter1, const T_getter2& _A_getter2)
182   { return compose2_functor<T_setter, T_getter1, T_getter2>(_A_setter, _A_getter1, _A_getter2); }
183
184 } /* namespace sigc */
185 #endif /* _SIGC_ADAPTORS_COMPOSE_H_ */