1 | // Boost.Function library |
2 | |
3 | // Copyright Douglas Gregor 2001-2006 |
4 | // Copyright Emil Dotchevski 2007 |
5 | // Use, modification and distribution is subject to the Boost Software License, Version 1.0. |
6 | // (See accompanying file LICENSE_1_0.txt or copy at |
7 | // http://www.boost.org/LICENSE_1_0.txt) |
8 | |
9 | // For more information, see http://www.boost.org |
10 | |
11 | // Note: this header is a header template and must NOT have multiple-inclusion |
12 | // protection. |
13 | #include <boost/function/detail/prologue.hpp> |
14 | #include <boost/detail/no_exceptions_support.hpp> |
15 | |
16 | #if defined(BOOST_MSVC) |
17 | # pragma warning( push ) |
18 | # pragma warning( disable : 4127 ) // "conditional expression is constant" |
19 | #endif |
20 | |
21 | #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T) |
22 | |
23 | #define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T) |
24 | |
25 | #define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I) |
26 | |
27 | #define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY) |
28 | |
29 | #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES |
30 | # define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a) |
31 | #else |
32 | # include <boost/move/utility_core.hpp> |
33 | # define BOOST_FUNCTION_ARG(J,I,D) ::boost::forward< BOOST_PP_CAT(T,I) >(BOOST_PP_CAT(a,I)) |
34 | # define BOOST_FUNCTION_ARGS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG,BOOST_PP_EMPTY) |
35 | #endif |
36 | |
37 | #define BOOST_FUNCTION_ARG_TYPE(J,I,D) \ |
38 | typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type); |
39 | |
40 | #define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY) |
41 | |
42 | // Comma if nonzero number of arguments |
43 | #if BOOST_FUNCTION_NUM_ARGS == 0 |
44 | # define BOOST_FUNCTION_COMMA |
45 | #else |
46 | # define BOOST_FUNCTION_COMMA , |
47 | #endif // BOOST_FUNCTION_NUM_ARGS > 0 |
48 | |
49 | // Class names used in this version of the code |
50 | #define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS) |
51 | #define BOOST_FUNCTION_FUNCTION_INVOKER \ |
52 | BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS) |
53 | #define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \ |
54 | BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS) |
55 | #define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \ |
56 | BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) |
57 | #define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \ |
58 | BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) |
59 | #define BOOST_FUNCTION_FUNCTION_REF_INVOKER \ |
60 | BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) |
61 | #define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \ |
62 | BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) |
63 | #define BOOST_FUNCTION_MEMBER_INVOKER \ |
64 | BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS) |
65 | #define BOOST_FUNCTION_VOID_MEMBER_INVOKER \ |
66 | BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS) |
67 | #define BOOST_FUNCTION_GET_FUNCTION_INVOKER \ |
68 | BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS) |
69 | #define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \ |
70 | BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) |
71 | #define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \ |
72 | BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) |
73 | #define BOOST_FUNCTION_GET_MEMBER_INVOKER \ |
74 | BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS) |
75 | #define BOOST_FUNCTION_GET_INVOKER \ |
76 | BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS) |
77 | #define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS) |
78 | |
79 | #ifndef BOOST_NO_VOID_RETURNS |
80 | # define BOOST_FUNCTION_VOID_RETURN_TYPE void |
81 | # define BOOST_FUNCTION_RETURN(X) X |
82 | #else |
83 | # define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable |
84 | # define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE () |
85 | #endif |
86 | |
87 | namespace boost { |
88 | namespace detail { |
89 | namespace function { |
90 | template< |
91 | typename FunctionPtr, |
92 | typename R BOOST_FUNCTION_COMMA |
93 | BOOST_FUNCTION_TEMPLATE_PARMS |
94 | > |
95 | struct BOOST_FUNCTION_FUNCTION_INVOKER |
96 | { |
97 | static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA |
98 | BOOST_FUNCTION_PARMS) |
99 | { |
100 | FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.members.func_ptr); |
101 | return f(BOOST_FUNCTION_ARGS); |
102 | } |
103 | }; |
104 | |
105 | template< |
106 | typename FunctionPtr, |
107 | typename R BOOST_FUNCTION_COMMA |
108 | BOOST_FUNCTION_TEMPLATE_PARMS |
109 | > |
110 | struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER |
111 | { |
112 | static BOOST_FUNCTION_VOID_RETURN_TYPE |
113 | invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA |
114 | BOOST_FUNCTION_PARMS) |
115 | |
116 | { |
117 | FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.members.func_ptr); |
118 | BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS)); |
119 | } |
120 | }; |
121 | |
122 | template< |
123 | typename FunctionObj, |
124 | typename R BOOST_FUNCTION_COMMA |
125 | BOOST_FUNCTION_TEMPLATE_PARMS |
126 | > |
127 | struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER |
128 | { |
129 | static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA |
130 | BOOST_FUNCTION_PARMS) |
131 | |
132 | { |
133 | FunctionObj* f; |
134 | if (function_allows_small_object_optimization<FunctionObj>::value) |
135 | f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data); |
136 | else |
137 | f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr); |
138 | return (*f)(BOOST_FUNCTION_ARGS); |
139 | } |
140 | }; |
141 | |
142 | template< |
143 | typename FunctionObj, |
144 | typename R BOOST_FUNCTION_COMMA |
145 | BOOST_FUNCTION_TEMPLATE_PARMS |
146 | > |
147 | struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER |
148 | { |
149 | static BOOST_FUNCTION_VOID_RETURN_TYPE |
150 | invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA |
151 | BOOST_FUNCTION_PARMS) |
152 | |
153 | { |
154 | FunctionObj* f; |
155 | if (function_allows_small_object_optimization<FunctionObj>::value) |
156 | f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data); |
157 | else |
158 | f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr); |
159 | BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); |
160 | } |
161 | }; |
162 | |
163 | template< |
164 | typename FunctionObj, |
165 | typename R BOOST_FUNCTION_COMMA |
166 | BOOST_FUNCTION_TEMPLATE_PARMS |
167 | > |
168 | struct BOOST_FUNCTION_FUNCTION_REF_INVOKER |
169 | { |
170 | static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA |
171 | BOOST_FUNCTION_PARMS) |
172 | |
173 | { |
174 | FunctionObj* f = |
175 | reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr); |
176 | return (*f)(BOOST_FUNCTION_ARGS); |
177 | } |
178 | }; |
179 | |
180 | template< |
181 | typename FunctionObj, |
182 | typename R BOOST_FUNCTION_COMMA |
183 | BOOST_FUNCTION_TEMPLATE_PARMS |
184 | > |
185 | struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER |
186 | { |
187 | static BOOST_FUNCTION_VOID_RETURN_TYPE |
188 | invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA |
189 | BOOST_FUNCTION_PARMS) |
190 | |
191 | { |
192 | FunctionObj* f = |
193 | reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr); |
194 | BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); |
195 | } |
196 | }; |
197 | |
198 | #if BOOST_FUNCTION_NUM_ARGS > 0 |
199 | /* Handle invocation of member pointers. */ |
200 | template< |
201 | typename MemberPtr, |
202 | typename R BOOST_FUNCTION_COMMA |
203 | BOOST_FUNCTION_TEMPLATE_PARMS |
204 | > |
205 | struct BOOST_FUNCTION_MEMBER_INVOKER |
206 | { |
207 | static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA |
208 | BOOST_FUNCTION_PARMS) |
209 | |
210 | { |
211 | MemberPtr* f = |
212 | reinterpret_cast<MemberPtr*>(function_obj_ptr.data); |
213 | return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS); |
214 | } |
215 | }; |
216 | |
217 | template< |
218 | typename MemberPtr, |
219 | typename R BOOST_FUNCTION_COMMA |
220 | BOOST_FUNCTION_TEMPLATE_PARMS |
221 | > |
222 | struct BOOST_FUNCTION_VOID_MEMBER_INVOKER |
223 | { |
224 | static BOOST_FUNCTION_VOID_RETURN_TYPE |
225 | invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA |
226 | BOOST_FUNCTION_PARMS) |
227 | |
228 | { |
229 | MemberPtr* f = |
230 | reinterpret_cast<MemberPtr*>(function_obj_ptr.data); |
231 | BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS)); |
232 | } |
233 | }; |
234 | #endif |
235 | |
236 | template< |
237 | typename FunctionPtr, |
238 | typename R BOOST_FUNCTION_COMMA |
239 | BOOST_FUNCTION_TEMPLATE_PARMS |
240 | > |
241 | struct BOOST_FUNCTION_GET_FUNCTION_INVOKER |
242 | { |
243 | typedef typename mpl::if_c<(is_void<R>::value), |
244 | BOOST_FUNCTION_VOID_FUNCTION_INVOKER< |
245 | FunctionPtr, |
246 | R BOOST_FUNCTION_COMMA |
247 | BOOST_FUNCTION_TEMPLATE_ARGS |
248 | >, |
249 | BOOST_FUNCTION_FUNCTION_INVOKER< |
250 | FunctionPtr, |
251 | R BOOST_FUNCTION_COMMA |
252 | BOOST_FUNCTION_TEMPLATE_ARGS |
253 | > |
254 | >::type type; |
255 | }; |
256 | |
257 | template< |
258 | typename FunctionObj, |
259 | typename R BOOST_FUNCTION_COMMA |
260 | BOOST_FUNCTION_TEMPLATE_PARMS |
261 | > |
262 | struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER |
263 | { |
264 | typedef typename mpl::if_c<(is_void<R>::value), |
265 | BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER< |
266 | FunctionObj, |
267 | R BOOST_FUNCTION_COMMA |
268 | BOOST_FUNCTION_TEMPLATE_ARGS |
269 | >, |
270 | BOOST_FUNCTION_FUNCTION_OBJ_INVOKER< |
271 | FunctionObj, |
272 | R BOOST_FUNCTION_COMMA |
273 | BOOST_FUNCTION_TEMPLATE_ARGS |
274 | > |
275 | >::type type; |
276 | }; |
277 | |
278 | template< |
279 | typename FunctionObj, |
280 | typename R BOOST_FUNCTION_COMMA |
281 | BOOST_FUNCTION_TEMPLATE_PARMS |
282 | > |
283 | struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER |
284 | { |
285 | typedef typename mpl::if_c<(is_void<R>::value), |
286 | BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER< |
287 | FunctionObj, |
288 | R BOOST_FUNCTION_COMMA |
289 | BOOST_FUNCTION_TEMPLATE_ARGS |
290 | >, |
291 | BOOST_FUNCTION_FUNCTION_REF_INVOKER< |
292 | FunctionObj, |
293 | R BOOST_FUNCTION_COMMA |
294 | BOOST_FUNCTION_TEMPLATE_ARGS |
295 | > |
296 | >::type type; |
297 | }; |
298 | |
299 | #if BOOST_FUNCTION_NUM_ARGS > 0 |
300 | /* Retrieve the appropriate invoker for a member pointer. */ |
301 | template< |
302 | typename MemberPtr, |
303 | typename R BOOST_FUNCTION_COMMA |
304 | BOOST_FUNCTION_TEMPLATE_PARMS |
305 | > |
306 | struct BOOST_FUNCTION_GET_MEMBER_INVOKER |
307 | { |
308 | typedef typename mpl::if_c<(is_void<R>::value), |
309 | BOOST_FUNCTION_VOID_MEMBER_INVOKER< |
310 | MemberPtr, |
311 | R BOOST_FUNCTION_COMMA |
312 | BOOST_FUNCTION_TEMPLATE_ARGS |
313 | >, |
314 | BOOST_FUNCTION_MEMBER_INVOKER< |
315 | MemberPtr, |
316 | R BOOST_FUNCTION_COMMA |
317 | BOOST_FUNCTION_TEMPLATE_ARGS |
318 | > |
319 | >::type type; |
320 | }; |
321 | #endif |
322 | |
323 | /* Given the tag returned by get_function_tag, retrieve the |
324 | actual invoker that will be used for the given function |
325 | object. |
326 | |
327 | Each specialization contains an "apply" nested class template |
328 | that accepts the function object, return type, function |
329 | argument types, and allocator. The resulting "apply" class |
330 | contains two typedefs, "invoker_type" and "manager_type", |
331 | which correspond to the invoker and manager types. */ |
332 | template<typename Tag> |
333 | struct BOOST_FUNCTION_GET_INVOKER { }; |
334 | |
335 | /* Retrieve the invoker for a function pointer. */ |
336 | template<> |
337 | struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag> |
338 | { |
339 | template<typename FunctionPtr, |
340 | typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> |
341 | struct apply |
342 | { |
343 | typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER< |
344 | FunctionPtr, |
345 | R BOOST_FUNCTION_COMMA |
346 | BOOST_FUNCTION_TEMPLATE_ARGS |
347 | >::type |
348 | invoker_type; |
349 | |
350 | typedef functor_manager<FunctionPtr> manager_type; |
351 | }; |
352 | |
353 | template<typename FunctionPtr, |
354 | typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS, |
355 | typename Allocator> |
356 | struct apply_a |
357 | { |
358 | typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER< |
359 | FunctionPtr, |
360 | R BOOST_FUNCTION_COMMA |
361 | BOOST_FUNCTION_TEMPLATE_ARGS |
362 | >::type |
363 | invoker_type; |
364 | |
365 | typedef functor_manager<FunctionPtr> manager_type; |
366 | }; |
367 | }; |
368 | |
369 | #if BOOST_FUNCTION_NUM_ARGS > 0 |
370 | /* Retrieve the invoker for a member pointer. */ |
371 | template<> |
372 | struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag> |
373 | { |
374 | template<typename MemberPtr, |
375 | typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> |
376 | struct apply |
377 | { |
378 | typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER< |
379 | MemberPtr, |
380 | R BOOST_FUNCTION_COMMA |
381 | BOOST_FUNCTION_TEMPLATE_ARGS |
382 | >::type |
383 | invoker_type; |
384 | |
385 | typedef functor_manager<MemberPtr> manager_type; |
386 | }; |
387 | |
388 | template<typename MemberPtr, |
389 | typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS, |
390 | typename Allocator> |
391 | struct apply_a |
392 | { |
393 | typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER< |
394 | MemberPtr, |
395 | R BOOST_FUNCTION_COMMA |
396 | BOOST_FUNCTION_TEMPLATE_ARGS |
397 | >::type |
398 | invoker_type; |
399 | |
400 | typedef functor_manager<MemberPtr> manager_type; |
401 | }; |
402 | }; |
403 | #endif |
404 | |
405 | /* Retrieve the invoker for a function object. */ |
406 | template<> |
407 | struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag> |
408 | { |
409 | template<typename FunctionObj, |
410 | typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> |
411 | struct apply |
412 | { |
413 | typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER< |
414 | FunctionObj, |
415 | R BOOST_FUNCTION_COMMA |
416 | BOOST_FUNCTION_TEMPLATE_ARGS |
417 | >::type |
418 | invoker_type; |
419 | |
420 | typedef functor_manager<FunctionObj> manager_type; |
421 | }; |
422 | |
423 | template<typename FunctionObj, |
424 | typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS, |
425 | typename Allocator> |
426 | struct apply_a |
427 | { |
428 | typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER< |
429 | FunctionObj, |
430 | R BOOST_FUNCTION_COMMA |
431 | BOOST_FUNCTION_TEMPLATE_ARGS |
432 | >::type |
433 | invoker_type; |
434 | |
435 | typedef functor_manager_a<FunctionObj, Allocator> manager_type; |
436 | }; |
437 | }; |
438 | |
439 | /* Retrieve the invoker for a reference to a function object. */ |
440 | template<> |
441 | struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag> |
442 | { |
443 | template<typename RefWrapper, |
444 | typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> |
445 | struct apply |
446 | { |
447 | typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER< |
448 | typename RefWrapper::type, |
449 | R BOOST_FUNCTION_COMMA |
450 | BOOST_FUNCTION_TEMPLATE_ARGS |
451 | >::type |
452 | invoker_type; |
453 | |
454 | typedef reference_manager<typename RefWrapper::type> manager_type; |
455 | }; |
456 | |
457 | template<typename RefWrapper, |
458 | typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS, |
459 | typename Allocator> |
460 | struct apply_a |
461 | { |
462 | typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER< |
463 | typename RefWrapper::type, |
464 | R BOOST_FUNCTION_COMMA |
465 | BOOST_FUNCTION_TEMPLATE_ARGS |
466 | >::type |
467 | invoker_type; |
468 | |
469 | typedef reference_manager<typename RefWrapper::type> manager_type; |
470 | }; |
471 | }; |
472 | |
473 | |
474 | /** |
475 | * vtable for a specific boost::function instance. This |
476 | * structure must be an aggregate so that we can use static |
477 | * initialization in boost::function's assign_to and assign_to_a |
478 | * members. It therefore cannot have any constructors, |
479 | * destructors, base classes, etc. |
480 | */ |
481 | template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> |
482 | struct BOOST_FUNCTION_VTABLE |
483 | { |
484 | #ifndef BOOST_NO_VOID_RETURNS |
485 | typedef R result_type; |
486 | #else |
487 | typedef typename function_return_type<R>::type result_type; |
488 | #endif // BOOST_NO_VOID_RETURNS |
489 | |
490 | typedef result_type (*invoker_type)(function_buffer& |
491 | BOOST_FUNCTION_COMMA |
492 | BOOST_FUNCTION_TEMPLATE_ARGS); |
493 | |
494 | template<typename F> |
495 | bool assign_to(F f, function_buffer& functor) const |
496 | { |
497 | typedef typename get_function_tag<F>::type tag; |
498 | return assign_to(f, functor, tag()); |
499 | } |
500 | template<typename F,typename Allocator> |
501 | bool assign_to_a(F f, function_buffer& functor, Allocator a) const |
502 | { |
503 | typedef typename get_function_tag<F>::type tag; |
504 | return assign_to_a(f, functor, a, tag()); |
505 | } |
506 | |
507 | void clear(function_buffer& functor) const |
508 | { |
509 | if (base.manager) |
510 | base.manager(functor, functor, destroy_functor_tag); |
511 | } |
512 | |
513 | private: |
514 | // Function pointers |
515 | template<typename FunctionPtr> |
516 | bool |
517 | assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const |
518 | { |
519 | this->clear(functor); |
520 | if (f) { |
521 | // should be a reinterpret cast, but some compilers insist |
522 | // on giving cv-qualifiers to free functions |
523 | functor.members.func_ptr = reinterpret_cast<void (*)()>(f); |
524 | return true; |
525 | } else { |
526 | return false; |
527 | } |
528 | } |
529 | template<typename FunctionPtr,typename Allocator> |
530 | bool |
531 | assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const |
532 | { |
533 | return assign_to(f,functor,function_ptr_tag()); |
534 | } |
535 | |
536 | // Member pointers |
537 | #if BOOST_FUNCTION_NUM_ARGS > 0 |
538 | template<typename MemberPtr> |
539 | bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const |
540 | { |
541 | // DPG TBD: Add explicit support for member function |
542 | // objects, so we invoke through mem_fn() but we retain the |
543 | // right target_type() values. |
544 | if (f) { |
545 | this->assign_to(boost::mem_fn(f), functor); |
546 | return true; |
547 | } else { |
548 | return false; |
549 | } |
550 | } |
551 | template<typename MemberPtr,typename Allocator> |
552 | bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const |
553 | { |
554 | // DPG TBD: Add explicit support for member function |
555 | // objects, so we invoke through mem_fn() but we retain the |
556 | // right target_type() values. |
557 | if (f) { |
558 | this->assign_to_a(boost::mem_fn(f), functor, a); |
559 | return true; |
560 | } else { |
561 | return false; |
562 | } |
563 | } |
564 | #endif // BOOST_FUNCTION_NUM_ARGS > 0 |
565 | |
566 | // Function objects |
567 | // Assign to a function object using the small object optimization |
568 | template<typename FunctionObj> |
569 | void |
570 | assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const |
571 | { |
572 | new (reinterpret_cast<void*>(functor.data)) FunctionObj(f); |
573 | } |
574 | template<typename FunctionObj,typename Allocator> |
575 | void |
576 | assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) const |
577 | { |
578 | assign_functor(f,functor,mpl::true_()); |
579 | } |
580 | |
581 | // Assign to a function object allocated on the heap. |
582 | template<typename FunctionObj> |
583 | void |
584 | assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) const |
585 | { |
586 | functor.members.obj_ptr = new FunctionObj(f); |
587 | } |
588 | template<typename FunctionObj,typename Allocator> |
589 | void |
590 | assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const |
591 | { |
592 | typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type; |
593 | typedef typename Allocator::template rebind<functor_wrapper_type>::other |
594 | wrapper_allocator_type; |
595 | typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type; |
596 | wrapper_allocator_type wrapper_allocator(a); |
597 | wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1); |
598 | wrapper_allocator.construct(copy, functor_wrapper_type(f,a)); |
599 | functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy); |
600 | functor.members.obj_ptr = new_f; |
601 | } |
602 | |
603 | template<typename FunctionObj> |
604 | bool |
605 | assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const |
606 | { |
607 | if (!boost::detail::function::has_empty_target(boost::addressof(f))) { |
608 | assign_functor(f, functor, |
609 | mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>()); |
610 | return true; |
611 | } else { |
612 | return false; |
613 | } |
614 | } |
615 | template<typename FunctionObj,typename Allocator> |
616 | bool |
617 | assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const |
618 | { |
619 | if (!boost::detail::function::has_empty_target(boost::addressof(f))) { |
620 | assign_functor_a(f, functor, a, |
621 | mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>()); |
622 | return true; |
623 | } else { |
624 | return false; |
625 | } |
626 | } |
627 | |
628 | // Reference to a function object |
629 | template<typename FunctionObj> |
630 | bool |
631 | assign_to(const reference_wrapper<FunctionObj>& f, |
632 | function_buffer& functor, function_obj_ref_tag) const |
633 | { |
634 | functor.members.obj_ref.obj_ptr = (void *)(f.get_pointer()); |
635 | functor.members.obj_ref.is_const_qualified = is_const<FunctionObj>::value; |
636 | functor.members.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value; |
637 | return true; |
638 | } |
639 | template<typename FunctionObj,typename Allocator> |
640 | bool |
641 | assign_to_a(const reference_wrapper<FunctionObj>& f, |
642 | function_buffer& functor, Allocator, function_obj_ref_tag) const |
643 | { |
644 | return assign_to(f,functor,function_obj_ref_tag()); |
645 | } |
646 | |
647 | public: |
648 | vtable_base base; |
649 | invoker_type invoker; |
650 | }; |
651 | } // end namespace function |
652 | } // end namespace detail |
653 | |
654 | template< |
655 | typename R BOOST_FUNCTION_COMMA |
656 | BOOST_FUNCTION_TEMPLATE_PARMS |
657 | > |
658 | class BOOST_FUNCTION_FUNCTION : public function_base |
659 | { |
660 | public: |
661 | #ifndef BOOST_NO_VOID_RETURNS |
662 | typedef R result_type; |
663 | #else |
664 | typedef typename boost::detail::function::function_return_type<R>::type |
665 | result_type; |
666 | #endif // BOOST_NO_VOID_RETURNS |
667 | |
668 | private: |
669 | typedef boost::detail::function::BOOST_FUNCTION_VTABLE< |
670 | R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> |
671 | vtable_type; |
672 | |
673 | vtable_type* get_vtable() const { |
674 | return reinterpret_cast<vtable_type*>( |
675 | reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01)); |
676 | } |
677 | |
678 | struct clear_type {}; |
679 | |
680 | public: |
681 | BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS); |
682 | |
683 | // add signature for boost::lambda |
684 | template<typename Args> |
685 | struct sig |
686 | { |
687 | typedef result_type type; |
688 | }; |
689 | |
690 | #if BOOST_FUNCTION_NUM_ARGS == 1 |
691 | typedef T0 argument_type; |
692 | #elif BOOST_FUNCTION_NUM_ARGS == 2 |
693 | typedef T0 first_argument_type; |
694 | typedef T1 second_argument_type; |
695 | #endif |
696 | |
697 | BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS); |
698 | BOOST_FUNCTION_ARG_TYPES |
699 | |
700 | typedef BOOST_FUNCTION_FUNCTION self_type; |
701 | |
702 | BOOST_FUNCTION_FUNCTION() : function_base() { } |
703 | |
704 | // MSVC chokes if the following two constructors are collapsed into |
705 | // one with a default parameter. |
706 | template<typename Functor> |
707 | BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f |
708 | #ifndef BOOST_NO_SFINAE |
709 | ,typename boost::enable_if_c< |
710 | !(is_integral<Functor>::value), |
711 | int>::type = 0 |
712 | #endif // BOOST_NO_SFINAE |
713 | ) : |
714 | function_base() |
715 | { |
716 | this->assign_to(f); |
717 | } |
718 | template<typename Functor,typename Allocator> |
719 | BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a |
720 | #ifndef BOOST_NO_SFINAE |
721 | ,typename boost::enable_if_c< |
722 | !(is_integral<Functor>::value), |
723 | int>::type = 0 |
724 | #endif // BOOST_NO_SFINAE |
725 | ) : |
726 | function_base() |
727 | { |
728 | this->assign_to_a(f,a); |
729 | } |
730 | |
731 | #ifndef BOOST_NO_SFINAE |
732 | BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { } |
733 | #else |
734 | BOOST_FUNCTION_FUNCTION(int zero) : function_base() |
735 | { |
736 | BOOST_ASSERT(zero == 0); |
737 | } |
738 | #endif |
739 | |
740 | BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base() |
741 | { |
742 | this->assign_to_own(f); |
743 | } |
744 | |
745 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES |
746 | BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base() |
747 | { |
748 | this->move_assign(f); |
749 | } |
750 | #endif |
751 | |
752 | ~BOOST_FUNCTION_FUNCTION() { clear(); } |
753 | |
754 | result_type operator()(BOOST_FUNCTION_PARMS) const |
755 | { |
756 | if (this->empty()) |
757 | boost::throw_exception(bad_function_call()); |
758 | |
759 | return get_vtable()->invoker |
760 | (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); |
761 | } |
762 | |
763 | // The distinction between when to use BOOST_FUNCTION_FUNCTION and |
764 | // when to use self_type is obnoxious. MSVC cannot handle self_type as |
765 | // the return type of these assignment operators, but Borland C++ cannot |
766 | // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to |
767 | // construct. |
768 | template<typename Functor> |
769 | #ifndef BOOST_NO_SFINAE |
770 | typename boost::enable_if_c< |
771 | !(is_integral<Functor>::value), |
772 | BOOST_FUNCTION_FUNCTION&>::type |
773 | #else |
774 | BOOST_FUNCTION_FUNCTION& |
775 | #endif |
776 | operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) |
777 | { |
778 | this->clear(); |
779 | BOOST_TRY { |
780 | this->assign_to(f); |
781 | } BOOST_CATCH (...) { |
782 | vtable = 0; |
783 | BOOST_RETHROW; |
784 | } |
785 | BOOST_CATCH_END |
786 | return *this; |
787 | } |
788 | template<typename Functor,typename Allocator> |
789 | void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a) |
790 | { |
791 | this->clear(); |
792 | BOOST_TRY{ |
793 | this->assign_to_a(f,a); |
794 | } BOOST_CATCH (...) { |
795 | vtable = 0; |
796 | BOOST_RETHROW; |
797 | } |
798 | BOOST_CATCH_END |
799 | } |
800 | |
801 | #ifndef BOOST_NO_SFINAE |
802 | BOOST_FUNCTION_FUNCTION& operator=(clear_type*) |
803 | { |
804 | this->clear(); |
805 | return *this; |
806 | } |
807 | #else |
808 | BOOST_FUNCTION_FUNCTION& operator=(int zero) |
809 | { |
810 | BOOST_ASSERT(zero == 0); |
811 | this->clear(); |
812 | return *this; |
813 | } |
814 | #endif |
815 | |
816 | // Assignment from another BOOST_FUNCTION_FUNCTION |
817 | BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f) |
818 | { |
819 | if (&f == this) |
820 | return *this; |
821 | |
822 | this->clear(); |
823 | BOOST_TRY { |
824 | this->assign_to_own(f); |
825 | } BOOST_CATCH (...) { |
826 | vtable = 0; |
827 | BOOST_RETHROW; |
828 | } |
829 | BOOST_CATCH_END |
830 | return *this; |
831 | } |
832 | |
833 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES |
834 | // Move assignment from another BOOST_FUNCTION_FUNCTION |
835 | BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f) |
836 | { |
837 | if (&f == this) |
838 | return *this; |
839 | |
840 | this->clear(); |
841 | BOOST_TRY { |
842 | this->move_assign(f); |
843 | } BOOST_CATCH (...) { |
844 | vtable = 0; |
845 | BOOST_RETHROW; |
846 | } |
847 | BOOST_CATCH_END |
848 | return *this; |
849 | } |
850 | #endif |
851 | |
852 | void swap(BOOST_FUNCTION_FUNCTION& other) |
853 | { |
854 | if (&other == this) |
855 | return; |
856 | |
857 | BOOST_FUNCTION_FUNCTION tmp; |
858 | tmp.move_assign(*this); |
859 | this->move_assign(other); |
860 | other.move_assign(tmp); |
861 | } |
862 | |
863 | // Clear out a target, if there is one |
864 | void clear() |
865 | { |
866 | if (vtable) { |
867 | if (!this->has_trivial_copy_and_destroy()) |
868 | get_vtable()->clear(this->functor); |
869 | vtable = 0; |
870 | } |
871 | } |
872 | |
873 | #if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG) |
874 | // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it |
875 | operator bool () const { return !this->empty(); } |
876 | #else |
877 | private: |
878 | struct dummy { |
879 | void nonnull() {} |
880 | }; |
881 | |
882 | typedef void (dummy::*safe_bool)(); |
883 | |
884 | public: |
885 | operator safe_bool () const |
886 | { return (this->empty())? 0 : &dummy::nonnull; } |
887 | |
888 | bool operator!() const |
889 | { return this->empty(); } |
890 | #endif |
891 | |
892 | private: |
893 | void assign_to_own(const BOOST_FUNCTION_FUNCTION& f) |
894 | { |
895 | if (!f.empty()) { |
896 | this->vtable = f.vtable; |
897 | if (this->has_trivial_copy_and_destroy()) |
898 | this->functor = f.functor; |
899 | else |
900 | get_vtable()->base.manager(f.functor, this->functor, |
901 | boost::detail::function::clone_functor_tag); |
902 | } |
903 | } |
904 | |
905 | template<typename Functor> |
906 | void assign_to(Functor f) |
907 | { |
908 | using boost::detail::function::vtable_base; |
909 | |
910 | typedef typename boost::detail::function::get_function_tag<Functor>::type tag; |
911 | typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker; |
912 | typedef typename get_invoker:: |
913 | template apply<Functor, R BOOST_FUNCTION_COMMA |
914 | BOOST_FUNCTION_TEMPLATE_ARGS> |
915 | handler_type; |
916 | |
917 | typedef typename handler_type::invoker_type invoker_type; |
918 | typedef typename handler_type::manager_type manager_type; |
919 | |
920 | // Note: it is extremely important that this initialization use |
921 | // static initialization. Otherwise, we will have a race |
922 | // condition here in multi-threaded code. See |
923 | // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. |
924 | static const vtable_type stored_vtable = |
925 | { { &manager_type::manage }, &invoker_type::invoke }; |
926 | |
927 | if (stored_vtable.assign_to(f, functor)) { |
928 | std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base); |
929 | // coverity[pointless_expression]: suppress coverity warnings on apparant if(const). |
930 | if (boost::has_trivial_copy_constructor<Functor>::value && |
931 | boost::has_trivial_destructor<Functor>::value && |
932 | boost::detail::function::function_allows_small_object_optimization<Functor>::value) |
933 | value |= static_cast<std::size_t>(0x01); |
934 | vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value); |
935 | } else |
936 | vtable = 0; |
937 | } |
938 | |
939 | template<typename Functor,typename Allocator> |
940 | void assign_to_a(Functor f,Allocator a) |
941 | { |
942 | using boost::detail::function::vtable_base; |
943 | |
944 | typedef typename boost::detail::function::get_function_tag<Functor>::type tag; |
945 | typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker; |
946 | typedef typename get_invoker:: |
947 | template apply_a<Functor, R BOOST_FUNCTION_COMMA |
948 | BOOST_FUNCTION_TEMPLATE_ARGS, |
949 | Allocator> |
950 | handler_type; |
951 | |
952 | typedef typename handler_type::invoker_type invoker_type; |
953 | typedef typename handler_type::manager_type manager_type; |
954 | |
955 | // Note: it is extremely important that this initialization use |
956 | // static initialization. Otherwise, we will have a race |
957 | // condition here in multi-threaded code. See |
958 | // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. |
959 | static const vtable_type stored_vtable = |
960 | { { &manager_type::manage }, &invoker_type::invoke }; |
961 | |
962 | if (stored_vtable.assign_to_a(f, functor, a)) { |
963 | std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base); |
964 | // coverity[pointless_expression]: suppress coverity warnings on apparant if(const). |
965 | if (boost::has_trivial_copy_constructor<Functor>::value && |
966 | boost::has_trivial_destructor<Functor>::value && |
967 | boost::detail::function::function_allows_small_object_optimization<Functor>::value) |
968 | value |= static_cast<std::size_t>(0x01); |
969 | vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value); |
970 | } else |
971 | vtable = 0; |
972 | } |
973 | |
974 | // Moves the value from the specified argument to *this. If the argument |
975 | // has its function object allocated on the heap, move_assign will pass |
976 | // its buffer to *this, and set the argument's buffer pointer to NULL. |
977 | void move_assign(BOOST_FUNCTION_FUNCTION& f) |
978 | { |
979 | if (&f == this) |
980 | return; |
981 | |
982 | BOOST_TRY { |
983 | if (!f.empty()) { |
984 | this->vtable = f.vtable; |
985 | if (this->has_trivial_copy_and_destroy()) |
986 | this->functor = f.functor; |
987 | else |
988 | get_vtable()->base.manager(f.functor, this->functor, |
989 | boost::detail::function::move_functor_tag); |
990 | f.vtable = 0; |
991 | } else { |
992 | clear(); |
993 | } |
994 | } BOOST_CATCH (...) { |
995 | vtable = 0; |
996 | BOOST_RETHROW; |
997 | } |
998 | BOOST_CATCH_END |
999 | } |
1000 | }; |
1001 | |
1002 | template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> |
1003 | inline void swap(BOOST_FUNCTION_FUNCTION< |
1004 | R BOOST_FUNCTION_COMMA |
1005 | BOOST_FUNCTION_TEMPLATE_ARGS |
1006 | >& f1, |
1007 | BOOST_FUNCTION_FUNCTION< |
1008 | R BOOST_FUNCTION_COMMA |
1009 | BOOST_FUNCTION_TEMPLATE_ARGS |
1010 | >& f2) |
1011 | { |
1012 | f1.swap(f2); |
1013 | } |
1014 | |
1015 | // Poison comparisons between boost::function objects of the same type. |
1016 | template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> |
1017 | void operator==(const BOOST_FUNCTION_FUNCTION< |
1018 | R BOOST_FUNCTION_COMMA |
1019 | BOOST_FUNCTION_TEMPLATE_ARGS>&, |
1020 | const BOOST_FUNCTION_FUNCTION< |
1021 | R BOOST_FUNCTION_COMMA |
1022 | BOOST_FUNCTION_TEMPLATE_ARGS>&); |
1023 | template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> |
1024 | void operator!=(const BOOST_FUNCTION_FUNCTION< |
1025 | R BOOST_FUNCTION_COMMA |
1026 | BOOST_FUNCTION_TEMPLATE_ARGS>&, |
1027 | const BOOST_FUNCTION_FUNCTION< |
1028 | R BOOST_FUNCTION_COMMA |
1029 | BOOST_FUNCTION_TEMPLATE_ARGS>& ); |
1030 | |
1031 | #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) |
1032 | |
1033 | #if BOOST_FUNCTION_NUM_ARGS == 0 |
1034 | #define BOOST_FUNCTION_PARTIAL_SPEC R (void) |
1035 | #else |
1036 | #define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T)) |
1037 | #endif |
1038 | |
1039 | template<typename R BOOST_FUNCTION_COMMA |
1040 | BOOST_FUNCTION_TEMPLATE_PARMS> |
1041 | class function<BOOST_FUNCTION_PARTIAL_SPEC> |
1042 | : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> |
1043 | { |
1044 | typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type; |
1045 | typedef function self_type; |
1046 | |
1047 | struct clear_type {}; |
1048 | |
1049 | public: |
1050 | |
1051 | function() : base_type() {} |
1052 | |
1053 | template<typename Functor> |
1054 | function(Functor f |
1055 | #ifndef BOOST_NO_SFINAE |
1056 | ,typename boost::enable_if_c< |
1057 | !(is_integral<Functor>::value), |
1058 | int>::type = 0 |
1059 | #endif |
1060 | ) : |
1061 | base_type(f) |
1062 | { |
1063 | } |
1064 | template<typename Functor,typename Allocator> |
1065 | function(Functor f, Allocator a |
1066 | #ifndef BOOST_NO_SFINAE |
1067 | ,typename boost::enable_if_c< |
1068 | !(is_integral<Functor>::value), |
1069 | int>::type = 0 |
1070 | #endif |
1071 | ) : |
1072 | base_type(f,a) |
1073 | { |
1074 | } |
1075 | |
1076 | #ifndef BOOST_NO_SFINAE |
1077 | function(clear_type*) : base_type() {} |
1078 | #endif |
1079 | |
1080 | function(const self_type& f) : base_type(static_cast<const base_type&>(f)){} |
1081 | |
1082 | function(const base_type& f) : base_type(static_cast<const base_type&>(f)){} |
1083 | |
1084 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES |
1085 | // Move constructors |
1086 | function(self_type&& f): base_type(static_cast<base_type&&>(f)){} |
1087 | function(base_type&& f): base_type(static_cast<base_type&&>(f)){} |
1088 | #endif |
1089 | |
1090 | self_type& operator=(const self_type& f) |
1091 | { |
1092 | self_type(f).swap(*this); |
1093 | return *this; |
1094 | } |
1095 | |
1096 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES |
1097 | self_type& operator=(self_type&& f) |
1098 | { |
1099 | self_type(static_cast<self_type&&>(f)).swap(*this); |
1100 | return *this; |
1101 | } |
1102 | #endif |
1103 | |
1104 | template<typename Functor> |
1105 | #ifndef BOOST_NO_SFINAE |
1106 | typename boost::enable_if_c< |
1107 | !(is_integral<Functor>::value), |
1108 | self_type&>::type |
1109 | #else |
1110 | self_type& |
1111 | #endif |
1112 | operator=(Functor f) |
1113 | { |
1114 | self_type(f).swap(*this); |
1115 | return *this; |
1116 | } |
1117 | |
1118 | #ifndef BOOST_NO_SFINAE |
1119 | self_type& operator=(clear_type*) |
1120 | { |
1121 | this->clear(); |
1122 | return *this; |
1123 | } |
1124 | #endif |
1125 | |
1126 | self_type& operator=(const base_type& f) |
1127 | { |
1128 | self_type(f).swap(*this); |
1129 | return *this; |
1130 | } |
1131 | |
1132 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES |
1133 | self_type& operator=(base_type&& f) |
1134 | { |
1135 | self_type(static_cast<base_type&&>(f)).swap(*this); |
1136 | return *this; |
1137 | } |
1138 | #endif |
1139 | }; |
1140 | |
1141 | #undef BOOST_FUNCTION_PARTIAL_SPEC |
1142 | #endif // have partial specialization |
1143 | |
1144 | } // end namespace boost |
1145 | |
1146 | // Cleanup after ourselves... |
1147 | #undef BOOST_FUNCTION_VTABLE |
1148 | #undef BOOST_FUNCTION_COMMA |
1149 | #undef BOOST_FUNCTION_FUNCTION |
1150 | #undef BOOST_FUNCTION_FUNCTION_INVOKER |
1151 | #undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER |
1152 | #undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER |
1153 | #undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER |
1154 | #undef BOOST_FUNCTION_FUNCTION_REF_INVOKER |
1155 | #undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER |
1156 | #undef BOOST_FUNCTION_MEMBER_INVOKER |
1157 | #undef BOOST_FUNCTION_VOID_MEMBER_INVOKER |
1158 | #undef BOOST_FUNCTION_GET_FUNCTION_INVOKER |
1159 | #undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER |
1160 | #undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER |
1161 | #undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER |
1162 | #undef BOOST_FUNCTION_GET_INVOKER |
1163 | #undef BOOST_FUNCTION_TEMPLATE_PARMS |
1164 | #undef BOOST_FUNCTION_TEMPLATE_ARGS |
1165 | #undef BOOST_FUNCTION_PARMS |
1166 | #undef BOOST_FUNCTION_PARM |
1167 | #ifdef BOOST_FUNCTION_ARG |
1168 | # undef BOOST_FUNCTION_ARG |
1169 | #endif |
1170 | #undef BOOST_FUNCTION_ARGS |
1171 | #undef BOOST_FUNCTION_ARG_TYPE |
1172 | #undef BOOST_FUNCTION_ARG_TYPES |
1173 | #undef BOOST_FUNCTION_VOID_RETURN_TYPE |
1174 | #undef BOOST_FUNCTION_RETURN |
1175 | |
1176 | #if defined(BOOST_MSVC) |
1177 | # pragma warning( pop ) |
1178 | #endif |
1179 | |