]> git.tdb.fi Git - ext/sigc++-2.0.git/blob - sigc++/functors/macros/mem_fun.h.m4
Import libsigc++ 2.10.8 sources
[ext/sigc++-2.0.git] / sigc++ / functors / macros / mem_fun.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([MEMBER_FUNCTOR],[dnl
22 /** [$2]mem_functor$1 wraps $4 methods with $1 argument(s).
23  * Use the convenience function mem_fun() to create an instance of [$2]mem_functor$1.
24  *
25  * The following template arguments are used:dnl
26 FOR(1,$1,[
27  * - @e T_arg%1 Argument type used in the definition of operator()().])
28  * - @e T_return The return type of operator()().
29  * - @e T_obj The object type.
30  *
31  * @ingroup mem_fun
32  */
33 template <LIST(class T_return, class T_obj, LOOP(class T_arg%1, $1))>
34 class [$2]mem_functor$1 : public functor_base
35 {
36 public:
37   typedef T_return (T_obj::*function_type)(LOOP(T_arg%1, $1)) $4;
38   typedef T_return result_type;
39
40   /// Constructs an invalid functor.
41   [$2]mem_functor$1() : func_ptr_(nullptr) {}
42
43   /** Constructs a [$2]mem_functor$1 object that wraps the passed method.
44    * @param _A_func Pointer to method will be invoked from operator()().
45    */
46   explicit [$2]mem_functor$1(function_type _A_func) : func_ptr_(_A_func) {}
47
48 #ifndef SIGCXX_DISABLE_DEPRECATED
49   /** Execute the wrapped method operating on the passed instance.
50    *
51    * @deprecated Please use the constructor that takes the object by reference
52    * instead.
53    *
54    * @param _A_obj Pointer to instance the method should operate on.dnl
55 FOR(1, $1,[
56    * @param _A_a%1 Argument to be passed on to the method.])
57    * @return The return value of the method invocation.
58    */
59   T_return operator()(LIST($3 T_obj* _A_obj, LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1))) const
60     { return (_A_obj->*(this->func_ptr_))(LOOP(_A_a%1, $1)); }
61 #endif //SIGCXX_DISABLE_DEPRECATED
62
63   /** Execute the wrapped method operating on the passed instance.
64    * @param _A_obj Reference to instance the method should operate on.dnl
65 FOR(1, $1,[
66    * @param _A_a%1 Argument to be passed on to the method.])
67    * @return The return value of the method invocation.
68    */
69   T_return operator()(LIST($3 T_obj& _A_obj, LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1))) const
70     { return (_A_obj.*func_ptr_)(LOOP(_A_a%1, $1)); }
71
72 protected:
73   function_type func_ptr_;
74 };
75
76 ])
77 define([BOUND_MEMBER_FUNCTOR],[dnl
78
79 /** bound_[$2]mem_functor$1 encapsulates a $4 method with $1 arguments and an object instance.
80  * Use the convenience function mem_fun() to create an instance of bound_[$2]mem_functor$1.
81  *
82  * The following template arguments are used:dnl
83 FOR(1,$1,[
84  * - @e T_arg%1 Argument type used in the definition of operator()().])
85  * - @e T_return The return type of operator()().
86  * - @e T_obj The object type.
87  *
88  * @ingroup mem_fun
89  */
90 template <LIST(class T_return, class T_obj, LOOP(class T_arg%1, $1))>
91 class bound_[$2]mem_functor$1
92   : public [$2]mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))>
93 {
94   typedef [$2]mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))> base_type_;
95 public:
96   typedef typename base_type_::function_type function_type;
97
98 #ifndef SIGCXX_DISABLE_DEPRECATED
99   /** Constructs a bound_[$2]mem_functor$1 object that wraps the passed method.
100    *
101    * @deprecated Please use the constructor that takes the object by reference
102    * instead.
103    *
104    * @param _A_obj Pointer to instance the method will operate on.
105    * @param _A_func Pointer to method will be invoked from operator()().
106    */
107   bound_[$2]mem_functor$1($3 T_obj* _A_obj, function_type _A_func)
108     : base_type_(_A_func),
109       obj_(*_A_obj)
110     {}
111 #endif // SIGCXX_DISABLE_DEPRECATED
112
113   /** Constructs a bound_[$2]mem_functor$1 object that wraps the passed method.
114    * @param _A_obj Reference to instance the method will operate on.
115    * @param _A_func Pointer to method will be invoked from operator()().
116    */
117   bound_[$2]mem_functor$1($3 T_obj& _A_obj, function_type _A_func)
118     : base_type_(_A_func),
119       obj_(_A_obj)
120     {}
121
122   /** Execute the wrapped method operating on the stored instance.dnl
123 FOR(1, $1,[
124    * @param _A_a%1 Argument to be passed on to the method.])
125    * @return The return value of the method invocation.
126    */
127   T_return operator()(LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)) const
128     { return (obj_.invoke().*(this->func_ptr_))(LOOP(_A_a%1, $1)); }
129
130 //protected:
131   // Reference to stored object instance.
132   // This is the handler object, such as TheObject in void TheObject::signal_handler().
133   [$2]limit_reference<T_obj> obj_;
134 };
135
136 #ifndef DOXYGEN_SHOULD_SKIP_THIS
137 //template specialization of visitor<>::do_visit_each<>(action, functor):
138 /** Performs a functor on each of the targets of a functor.
139  * The function overload for sigc::bound_[$2]mem_functor performs a functor
140  * on the object instance stored in the sigc::bound_[$2]mem_functor object.
141  *
142  * @ingroup mem_fun
143  */
144 template <LIST(class T_return, class T_obj, LOOP(class T_arg%1, $1))>
145 struct visitor<bound_[$2]mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))> >
146 {
147   template <class T_action>
148   static void do_visit_each(const T_action& _A_action,
149                             const bound_[$2]mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))>& _A_target)
150   {
151     sigc::visit_each(_A_action, _A_target.obj_);
152   }
153 };
154 #endif // DOXYGEN_SHOULD_SKIP_THIS
155 ])
156
157 define([MEM_FUN],[dnl
158 /** Creates a functor of type sigc::[$3]mem_functor$1 which wraps a $5 method.
159  * @param _A_func Pointer to method that should be wrapped.
160  * @return Functor that executes _A_func on invokation.
161  *
162  * @ingroup mem_fun
163  */
164 template <LIST(LOOP(class T_arg%1, $1), class T_return, class T_obj)>
165 inline [$3]mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))>
166 mem_fun[]ifelse($2,, $1)(T_return (T_obj::*_A_func)(LOOP(T_arg%1,$1)) $5)
167 { return [$3]mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))>(_A_func); }
168
169 ])
170 define([BOUND_MEM_FUN],[dnl
171 #ifndef SIGCXX_DISABLE_DEPRECATED
172 /** Creates a functor of type sigc::bound_[$3]mem_functor$1 which encapsulates a method and an object instance.
173  *
174  * @deprecated Please use the version that takes the object by reference instead.
175  *
176  * @param _A_obj Pointer to object instance the functor should operate on.
177  * @param _A_func Pointer to method that should be wrapped.
178  * @return Functor that executes @e _A_func on invokation.
179  *
180  * @ingroup mem_fun
181  */
182 template <LIST(LOOP(class T_arg%1, $1), class T_return, class T_obj, class T_obj2)>
183 inline bound_[$3]mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))>
184 mem_fun[]ifelse($2,, $1)(/*$4*/ T_obj* _A_obj, T_return (T_obj2::*_A_func)(LOOP(T_arg%1,$1)) $5)
185 { return bound_[$3]mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))>(_A_obj, _A_func); }
186 #endif //SIGCXX_DISABLE_DEPRECATED
187
188 /** Creates a functor of type sigc::bound_[$3]mem_functor$1 which encapsulates a method and an object instance.
189  * @param _A_obj Reference to object instance the functor should operate on.
190  * @param _A_func Pointer to method that should be wrapped.
191  * @return Functor that executes @e _A_func on invokation.
192  *
193  * @ingroup mem_fun
194  */
195 template <LIST(LOOP(class T_arg%1, $1), class T_return, class T_obj, class T_obj2)>
196 inline bound_[$3]mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))>
197 mem_fun[]ifelse($2,, $1)(/*$4*/ T_obj& _A_obj, T_return (T_obj2::*_A_func)(LOOP(T_arg%1,$1)) $5)
198 { return bound_[$3]mem_functor$1<LIST(T_return, T_obj, LOOP(T_arg%1, $1))>(_A_obj, _A_func); }
199
200 ])
201
202 divert(0)
203
204 // implementation notes:
205 //  - we do not use bind here, because it would introduce
206 //    an extra copy and complicate the header include order if bind is
207 //    to have automatic conversion for member pointers.
208 _FIREWALL([FUNCTORS_MEM_FUN])
209 #include <sigc++/type_traits.h>
210 #include <sigc++/functors/functor_trait.h>
211 #include <sigc++/limit_reference.h>
212
213 namespace sigc {
214
215 /** @defgroup mem_fun mem_fun()
216  * mem_fun() Creates a functor from a pointer to a method.
217  *
218  * Optionally, a reference or pointer to an object can be bound to the functor.
219  *
220  * @note If the object type inherits from sigc::trackable, and the
221  * functor returned from mem_fun() is assigned to a sigc::slot, the functor
222  * will be automatically cleared when the object goes out of scope. Invoking
223  * that slot will then have no effect and will not try to use the destroyed
224  * instance.
225  *
226  * If the member function pointer is to an overloaded type, you must specify
227  * the types using template arguments starting with the first argument.
228  * It is not necessary to supply the return type.
229  *
230  * @par Example:
231  * @code
232  * struct foo : public sigc::trackable
233  * {
234  *   void bar(int) {}
235  * };
236  * foo my_foo;
237  * sigc::slot<void, int> sl = sigc::mem_fun(my_foo, &foo::bar);
238  * // Note: f is not a slot. It will not be invalidated when my_foo is deleted.
239  * auto f = sigc::mem_fun(my_foo, &foo::bar); // Usually not what you want.
240  * @endcode
241  *
242  * For const methods mem_fun() takes a const reference or pointer to an object.
243  *
244  * @par Example:
245  * @code
246  * struct foo : public sigc::trackable
247  * {
248  *   void bar(int) const {}
249  * };
250  * const foo my_foo;
251  * sigc::slot<void, int> sl = sigc::mem_fun(my_foo, &foo::bar);
252  * @endcode
253  *
254  * Use mem_fun#() if there is an ambiguity as to the number of arguments.
255  *
256  * @par Example:
257  * @code
258  * struct foo : public sigc::trackable
259  * {
260  *   void bar(int) {}
261  *   void bar(float) {}
262  *   void bar(int, int) {}
263  * };
264  * foo my_foo;
265  * sigc::slot<void, int> sl = sigc::mem_fun1<int>(my_foo, &foo::bar);
266  * @endcode
267  *
268  * @ingroup sigcfunctors
269  */
270
271 FOR(0,CALL_SIZE,[[MEMBER_FUNCTOR(%1,[],[],[])]])dnl
272 FOR(0,CALL_SIZE,[[MEMBER_FUNCTOR(%1,[const_],[const],[const])]])dnl
273 FOR(0,CALL_SIZE,[[MEMBER_FUNCTOR(%1,[volatile_],[],[volatile])]])dnl
274 FOR(0,CALL_SIZE,[[MEMBER_FUNCTOR(%1,[const_volatile_],[const],[const volatile])]])dnl
275 FOR(0,CALL_SIZE,[[BOUND_MEMBER_FUNCTOR(%1,[],[],[])]])dnl
276 FOR(0,CALL_SIZE,[[BOUND_MEMBER_FUNCTOR(%1,[const_],[const],[const])]])dnl
277 FOR(0,CALL_SIZE,[[BOUND_MEMBER_FUNCTOR(%1,[volatile_],[],[volatile])]])dnl
278 FOR(0,CALL_SIZE,[[BOUND_MEMBER_FUNCTOR(%1,[const_volatile_],[const],[const volatile])]])dnl
279
280 // numbered
281 FOR(0,CALL_SIZE,[[MEM_FUN(%1,,[],[],[])]])dnl
282 FOR(0,CALL_SIZE,[[MEM_FUN(%1,,[const_],[const],[const])]])dnl
283 FOR(0,CALL_SIZE,[[MEM_FUN(%1,,[volatile_],[],[volatile])]])dnl
284 FOR(0,CALL_SIZE,[[MEM_FUN(%1,,[const_volatile_],[const],[const volatile])]])dnl
285 FOR(0,CALL_SIZE,[[BOUND_MEM_FUN(%1,,[],[],[])]])dnl
286 FOR(0,CALL_SIZE,[[BOUND_MEM_FUN(%1,,[const_],[const],[const])]])dnl
287 FOR(0,CALL_SIZE,[[BOUND_MEM_FUN(%1,,[volatile_],[],[volatile])]])dnl
288 FOR(0,CALL_SIZE,[[BOUND_MEM_FUN(%1,,[const_volatile_],[const],[const volatile])]])dnl
289
290 // unnumbered
291 FOR(0,CALL_SIZE,[[MEM_FUN(%1,1,[],[],[])]])dnl
292 FOR(0,CALL_SIZE,[[MEM_FUN(%1,1,[const_],[const],[const])]])dnl
293 FOR(0,CALL_SIZE,[[MEM_FUN(%1,1,[volatile_],[],[volatile])]])dnl
294 FOR(0,CALL_SIZE,[[MEM_FUN(%1,1,[const_volatile_],[const],[const volatile])]])dnl
295 FOR(0,CALL_SIZE,[[BOUND_MEM_FUN(%1,1,[],[],[])]])dnl
296 FOR(0,CALL_SIZE,[[BOUND_MEM_FUN(%1,1,[const_],[const],[const])]])dnl
297 FOR(0,CALL_SIZE,[[BOUND_MEM_FUN(%1,1,[volatile_],[],[volatile])]])dnl
298 FOR(0,CALL_SIZE,[[BOUND_MEM_FUN(%1,1,[const_volatile_],[const],[const volatile])]])dnl
299
300 } /* namespace sigc */