1 #ifndef _SIGC_ADAPTORS_COMPOSE_H_
2 #define _SIGC_ADAPTORS_COMPOSE_H_
3 #include <sigc++/adaptors/adaptor_trait.h>
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.
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))
20 * The functor sigc::compose() returns can be passed directly into
21 * sigc::signal::connect().
25 * sigc::signal(float(float, float)> some_signal;
26 * some_signal.connect(sigc::compose(&square_root, &sum));
32 /** Adaptor that combines two functors.
33 * Use the convenience function sigc::compose() to create an instance of sigc::compose1_functor.
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.
41 template <class T_setter, class T_getter>
42 struct compose1_functor : public adapts<T_setter>
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;
51 { return this->functor_(get_()); }
54 template <class... T_arg>
56 operator()(T_arg&&... _A_a)
57 { return this->functor_(get_(std::forward<T_arg>(_A_a)...));
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()().
64 compose1_functor(const T_setter& _A_setter, const T_getter& _A_getter)
65 : adapts<T_setter>(_A_setter), get_(_A_getter)
68 getter_type get_; // public, so that visit_each() can access it
71 /** Adaptor that combines three functors.
72 * Use the convenience function sigc::compose() to create an instance of sigc::compose2_functor.
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.
81 template <class T_setter, class T_getter1, class T_getter2>
82 struct compose2_functor : public adapts<T_setter>
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;
92 { return this->functor_(get1_(), get2_()); }
95 template <class... T_arg>
97 operator()(T_arg... _A_a)
98 { return this->functor_(get1_(_A_a...), get2_(_A_a...));
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()().
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)
112 getter1_type get1_; // public, so that visit_each() can access it
113 getter2_type get2_; // public, so that visit_each() can access it
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.
124 template <class T_setter, class T_getter>
125 struct visitor<compose1_functor<T_setter, T_getter> >
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)
131 sigc::visit_each(_A_action, _A_target.functor_);
132 sigc::visit_each(_A_action, _A_target.get_);
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.
143 template <class T_setter, class T_getter1, class T_getter2>
144 struct visitor<compose2_functor<T_setter, T_getter1, T_getter2> >
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)
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_);
155 #endif // DOXYGEN_SHOULD_SKIP_THIS
157 /** Creates an adaptor of type sigc::compose1_functor which combines two functors.
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.
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); }
170 /** Creates an adaptor of type sigc::compose2_functor which combines three functors.
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.
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); }
184 } /* namespace sigc */
185 #endif /* _SIGC_ADAPTORS_COMPOSE_H_ */