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       {
invokeboost::detail::function::BOOST_FUNCTION_FUNCTION_INVOKER97         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
invokeboost::detail::function::BOOST_FUNCTION_VOID_FUNCTION_INVOKER113         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       {
invokeboost::detail::function::BOOST_FUNCTION_FUNCTION_OBJ_INVOKER129         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
invokeboost::detail::function::BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER150         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       {
invokeboost::detail::function::BOOST_FUNCTION_FUNCTION_REF_INVOKER170         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
invokeboost::detail::function::BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER188         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       {
invokeboost::detail::function::BOOST_FUNCTION_MEMBER_INVOKER207         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
invokeboost::detail::function::BOOST_FUNCTION_VOID_MEMBER_INVOKER225         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>
assign_toboost::detail::function::BOOST_FUNCTION_VTABLE495         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>
assign_to_aboost::detail::function::BOOST_FUNCTION_VTABLE501         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 
clearboost::detail::function::BOOST_FUNCTION_VTABLE507         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
assign_toboost::detail::function::BOOST_FUNCTION_VTABLE517         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
assign_to_aboost::detail::function::BOOST_FUNCTION_VTABLE531         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>
assign_toboost::detail::function::BOOST_FUNCTION_VTABLE539         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>
assign_to_aboost::detail::function::BOOST_FUNCTION_VTABLE552         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
assign_functorboost::detail::function::BOOST_FUNCTION_VTABLE570         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
assign_functor_aboost::detail::function::BOOST_FUNCTION_VTABLE576         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
assign_functorboost::detail::function::BOOST_FUNCTION_VTABLE584         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
assign_functor_aboost::detail::function::BOOST_FUNCTION_VTABLE590         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
assign_toboost::detail::function::BOOST_FUNCTION_VTABLE605         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
assign_to_aboost::detail::function::BOOST_FUNCTION_VTABLE617         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
assign_toboost::detail::function::BOOST_FUNCTION_VTABLE631         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
assign_to_aboost::detail::function::BOOST_FUNCTION_VTABLE641         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 
get_vtable() const673     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 
BOOST_FUNCTION_FUNCTION()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>
BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX (const &)f,typename boost::enable_if_c<!(is_integral<Functor>::value),int>::type=0)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>
BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX (const &)f,Allocator a,typename boost::enable_if_c<!(is_integral<Functor>::value),int>::type=0)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
BOOST_FUNCTION_FUNCTION(clear_type *)732     BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
733 #else
BOOST_FUNCTION_FUNCTION(int zero)734     BOOST_FUNCTION_FUNCTION(int zero) : function_base()
735     {
736       BOOST_ASSERT(zero == 0);
737     }
738 #endif
739 
BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION & f)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
BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION && f)746     BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base()
747     {
748       this->move_assign(f);
749     }
750 #endif
751 
~BOOST_FUNCTION_FUNCTION()752     ~BOOST_FUNCTION_FUNCTION() { clear(); }
753 
operator ()(BOOST_FUNCTION_PARMS) const754     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
operator =(Functor BOOST_FUNCTION_TARGET_FIX (const &)f)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>
assign(Functor BOOST_FUNCTION_TARGET_FIX (const &)f,Allocator a)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
operator =(clear_type *)802     BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
803     {
804       this->clear();
805       return *this;
806     }
807 #else
operator =(int zero)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
operator =(const BOOST_FUNCTION_FUNCTION & f)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
operator =(BOOST_FUNCTION_FUNCTION && f)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 
swap(BOOST_FUNCTION_FUNCTION & other)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
clear()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
operator bool() const875     operator bool () const { return !this->empty(); }
876 #else
877   private:
878     struct dummy {
nonnullboost::BOOST_FUNCTION_FUNCTION::dummy879       void nonnull() {}
880     };
881 
882     typedef void (dummy::*safe_bool)();
883 
884   public:
operator safe_bool() const885     operator safe_bool () const
886       { return (this->empty())? 0 : &dummy::nonnull; }
887 
operator !() const888     bool operator!() const
889       { return this->empty(); }
890 #endif
891 
892   private:
assign_to_own(const BOOST_FUNCTION_FUNCTION & f)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>
assign_to(Functor f)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>
assign_to_a(Functor f,Allocator a)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.
move_assign(BOOST_FUNCTION_FUNCTION & f)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>
swap(BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> & f1,BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> & f2)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 
function()1051   function() : base_type() {}
1052 
1053   template<typename Functor>
function(Functor f,typename boost::enable_if_c<!(is_integral<Functor>::value),int>::type=0)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>
function(Functor f,Allocator a,typename boost::enable_if_c<!(is_integral<Functor>::value),int>::type=0)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
function(clear_type *)1077   function(clear_type*) : base_type() {}
1078 #endif
1079 
function(const self_type & f)1080   function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
1081 
function(const base_type & f)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
function(self_type && f)1086   function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
function(base_type && f)1087   function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
1088 #endif
1089 
operator =(const self_type & f)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
operator =(self_type && f)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
operator =(Functor f)1112   operator=(Functor f)
1113   {
1114     self_type(f).swap(*this);
1115     return *this;
1116   }
1117 
1118 #ifndef BOOST_NO_SFINAE
operator =(clear_type *)1119   self_type& operator=(clear_type*)
1120   {
1121     this->clear();
1122     return *this;
1123   }
1124 #endif
1125 
operator =(const base_type & f)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
operator =(base_type && f)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