1 #ifndef _SIGC_FUNCTORS_MEM_FUN_H_
2 #define _SIGC_FUNCTORS_MEM_FUN_H_
3 #include <sigc++/type_traits.h>
4 #include <sigc++/limit_reference.h>
5 #include <sigc++/member_method_trait.h>
7 // implementation notes:
8 // - we do not use bind here, because it would introduce
9 // an extra copy and complicate the header include order if bind is
10 // to have automatic conversion for member pointers.
14 /** @defgroup mem_fun mem_fun()
15 * mem_fun() is used to convert a pointer to a method to a functor.
17 * Optionally, a reference or pointer to an object can be bound to the functor.
19 * @note Only if the object type inherits from sigc::trackable, and the
20 * functor returned from mem_fun() is assigned to a sigc::slot, is the functor
21 * automatically cleared when the object goes out of scope!
23 * If the member function pointer is to an overloaded type, you must specify
24 * the types using template arguments starting with the first argument.
25 * It is not necessary to supply the return type.
29 * struct foo : public sigc::trackable
34 * sigc::slot<void(int)> sl = sigc::mem_fun(my_foo, &foo::bar);
35 * // Note: f is not a slot. It will not be invalidated when my_foo is deleted.
36 * auto f = sigc::mem_fun(my_foo, &foo::bar); // Usually not what you want.
39 * For const methods mem_fun() takes a const reference or pointer to an object.
43 * struct foo : public sigc::trackable
45 * void bar(int) const {}
48 * sigc::slot<void(int)> sl = sigc::mem_fun(my_foo, &foo::bar);
51 * Use mem_fun#() if there is an ambiguity as to the number of arguments.
55 * struct foo : public sigc::trackable
59 * void bar(int, int) {}
62 * sigc::slot<void(int)> sl = sigc::mem_fun1<int>(my_foo, &foo::bar);
65 * @ingroup sigcfunctors
68 template <class T_func, class... T_arg>
69 class mem_functor : public functor_base
72 using object_type = typename internal::member_method_class<T_func>::type;
74 using function_type = T_func;
75 using result_type = typename internal::member_method_result<T_func>::type;
77 using obj_type_with_modifier = typename std::conditional_t<
78 internal::member_method_is_const<T_func>::value, const object_type, object_type>;
80 /// Constructs an invalid functor.
81 mem_functor() : func_ptr_(nullptr) {}
83 /** Constructs a mem_functor object that wraps the passed method.
84 * @param _A_func Pointer to method will be invoked from operator()().
86 explicit mem_functor(function_type _A_func) : func_ptr_(_A_func) {}
88 /** Execute the wrapped method operating on the passed instance.
89 * @param _A_obj Reference to instance the method should operate on.
90 * @param _A_a... Argument to be passed on to the method.
91 * @return The return value of the method invocation.
94 operator()(obj_type_with_modifier& _A_obj, type_trait_take_t<T_arg>... _A_a) const
95 { return (_A_obj.*func_ptr_)(_A_a...); }
98 function_type func_ptr_;
102 template <class T_func,
104 class bound_mem_functor
105 : mem_functor<T_func, T_arg...>
107 using base_type = mem_functor<T_func, T_arg...>;
109 using function_type = typename base_type::function_type;
110 using result_type = typename base_type::result_type;
112 using object_type = typename base_type::object_type;
114 using obj_type_with_modifier = typename std::conditional_t<
115 internal::member_method_is_const<T_func>::value, const object_type, object_type>;
116 using T_limit_reference = typename std::conditional_t<
117 internal::member_method_is_const<T_func>::value,
118 limit_reference<const object_type>, limit_reference<object_type>>;
120 /** Constructs a bound_mem_functor object that wraps the passed method.
121 * @param _A_obj Reference to instance the method will operate on.
122 * @param _A_func Pointer to method will be invoked from operator()().
124 bound_mem_functor(obj_type_with_modifier& _A_obj, function_type _A_func)
125 : base_type(_A_func),
129 /** Execute the wrapped method operating on the stored instance.
130 * @param _A_a... Argument to be passed on to the method.
131 * @return The return value of the method invocation.
134 operator()(type_trait_take_t<T_arg>... _A_a) const
135 { return (obj_.invoke().*(this->func_ptr_))(_A_a...); }
138 // Reference to stored object instance.
139 // This is the handler object, such as TheObject in void TheObject::signal_handler().
140 T_limit_reference obj_;
144 #ifndef DOXYGEN_SHOULD_SKIP_THIS
145 //template specialization of visitor<>::do_visit_each<>(action, functor):
146 /** Performs a functor on each of the targets of a functor.
147 * The function overload for sigc::bound_$1mem_functor performs a functor
148 * on the object instance stored in the sigc::bound_$1mem_functor object.
152 template <class T_func, class... T_arg>
153 struct visitor<bound_mem_functor<T_func, T_arg...> >
155 template <class T_action>
156 static void do_visit_each(const T_action& _A_action,
157 const bound_mem_functor<T_func, T_arg...>& _A_target)
159 sigc::visit_each(_A_action, _A_target.obj_);
162 #endif // DOXYGEN_SHOULD_SKIP_THIS
165 /** Creates a functor of type sigc::mem_functor which wraps a method.
166 * @param _A_func Pointer to method that should be wrapped.
167 * @return Functor that executes _A_func on invokation.
171 template <class T_return, class T_obj, class... T_arg>
172 inline decltype(auto)
173 mem_fun(T_return (T_obj::*_A_func)(T_arg...) )
174 { return mem_functor<
175 T_return (T_obj::*)(T_arg...) ,
176 T_arg...>(_A_func); }
179 /** Creates a functor of type sigc::const_mem_functor which wraps a const method.
180 * @param _A_func Pointer to method that should be wrapped.
181 * @return Functor that executes _A_func on invokation.
185 template <class T_return, class T_obj, class... T_arg>
186 inline decltype(auto)
187 mem_fun(T_return (T_obj::*_A_func)(T_arg...) const)
188 { return mem_functor<
189 T_return (T_obj::*)(T_arg...) const,
190 T_arg...>(_A_func); }
193 /** Creates a functor of type sigc::volatile_mem_functor which wraps a volatile method.
194 * @param _A_func Pointer to method that should be wrapped.
195 * @return Functor that executes _A_func on invokation.
199 template <class T_return, class T_obj, class... T_arg>
200 inline decltype(auto)
201 mem_fun(T_return (T_obj::*_A_func)(T_arg...) volatile)
202 { return mem_functor<
203 T_return (T_obj::*)(T_arg...) volatile,
204 T_arg...>(_A_func); }
207 /** Creates a functor of type sigc::const_volatile_mem_functor which wraps a const volatile method.
208 * @param _A_func Pointer to method that should be wrapped.
209 * @return Functor that executes _A_func on invokation.
213 template <class T_return, class T_obj, class... T_arg>
214 inline decltype(auto)
215 mem_fun(T_return (T_obj::*_A_func)(T_arg...) const volatile)
216 { return mem_functor<
217 T_return (T_obj::*)(T_arg...) const volatile,
218 T_arg...>(_A_func); }
221 /** Creates a functor of type sigc::bound_mem_functor which encapsulates a method and an object instance.
222 * @param _A_obj Reference to object instance the functor should operate on.
223 * @param _A_func Pointer to method that should be wrapped.
224 * @return Functor that executes @e _A_func on invokation.
228 template <class T_return, class T_obj, class T_obj2, class... T_arg>
229 inline decltype(auto)
230 mem_fun(/**/ T_obj& _A_obj, T_return (T_obj2::*_A_func)(T_arg...) )
232 return bound_mem_functor<
233 T_return (T_obj::*)(T_arg...) ,
234 T_arg...>(_A_obj, _A_func);
237 /** Creates a functor of type sigc::bound_const_mem_functor which encapsulates a method and an object instance.
238 * @param _A_obj Reference to object instance the functor should operate on.
239 * @param _A_func Pointer to method that should be wrapped.
240 * @return Functor that executes @e _A_func on invokation.
244 template <class T_return, class T_obj, class T_obj2, class... T_arg>
245 inline decltype(auto)
246 mem_fun(/*const*/ T_obj& _A_obj, T_return (T_obj2::*_A_func)(T_arg...) const)
248 return bound_mem_functor<
249 T_return (T_obj::*)(T_arg...) const,
250 T_arg...>(_A_obj, _A_func);
254 /** Creates a functor of type sigc::bound_volatile_mem_functor which encapsulates a method and an object instance.
255 * @param _A_obj Reference to object instance the functor should operate on.
256 * @param _A_func Pointer to method that should be wrapped.
257 * @return Functor that executes @e _A_func on invokation.
261 template <class T_return, class T_obj, class T_obj2, class... T_arg>
262 inline decltype(auto)
263 mem_fun(/**/ T_obj& _A_obj, T_return (T_obj2::*_A_func)(T_arg...) volatile)
265 return bound_mem_functor<
266 T_return (T_obj::*)(T_arg...) volatile,
267 T_arg...>(_A_obj, _A_func);
271 /** Creates a functor of type sigc::bound_const_volatile_mem_functor which encapsulates a method and an object instance.
272 * @param _A_obj Reference to object instance the functor should operate on.
273 * @param _A_func Pointer to method that should be wrapped.
274 * @return Functor that executes @e _A_func on invokation.
278 template <class T_return, class T_obj, class T_obj2, class... T_arg>
279 inline decltype(auto)
280 mem_fun(/*const*/ T_obj& _A_obj, T_return (T_obj2::*_A_func)(T_arg...) const volatile)
282 return bound_mem_functor<
283 T_return (T_obj::*)(T_arg...) const volatile,
284 T_arg...>(_A_obj, _A_func);
289 } /* namespace sigc */
290 #endif /* _SIGC_FUNCTORS_MEM_FUN_H_ */