1 // Boost.Function library
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)
9 // For more information, see http://www.boost.org
11 // Note: this header is a header template and must NOT have multiple-inclusion
13 #include <boost/function/detail/prologue.hpp>
15 #if defined(BOOST_MSVC)
16 # pragma warning( push )
17 # pragma warning( disable : 4127 ) // "conditional expression is constant"
20 #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
22 #define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
24 #define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
26 #define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
28 #define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
30 #define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
31 typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
33 #define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
35 // Comma if nonzero number of arguments
36 #if BOOST_FUNCTION_NUM_ARGS == 0
37 # define BOOST_FUNCTION_COMMA
39 # define BOOST_FUNCTION_COMMA ,
40 #endif // BOOST_FUNCTION_NUM_ARGS > 0
42 // Class names used in this version of the code
43 #define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
44 #define BOOST_FUNCTION_FUNCTION_INVOKER \
45 BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
46 #define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
47 BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
48 #define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
49 BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
50 #define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
51 BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
52 #define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
53 BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
54 #define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
55 BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
56 #define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
57 BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
58 #define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
59 BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
60 #define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
61 BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
62 #define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
64 #ifndef BOOST_NO_VOID_RETURNS
65 # define BOOST_FUNCTION_VOID_RETURN_TYPE void
66 # define BOOST_FUNCTION_RETURN(X) X
68 # define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
69 # define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
77 typename R BOOST_FUNCTION_COMMA
78 BOOST_FUNCTION_TEMPLATE_PARMS
80 struct BOOST_FUNCTION_FUNCTION_INVOKER
82 static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
85 FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
86 return f(BOOST_FUNCTION_ARGS);
92 typename R BOOST_FUNCTION_COMMA
93 BOOST_FUNCTION_TEMPLATE_PARMS
95 struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
97 static BOOST_FUNCTION_VOID_RETURN_TYPE
98 invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
102 FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
103 BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
108 typename FunctionObj,
109 typename R BOOST_FUNCTION_COMMA
110 BOOST_FUNCTION_TEMPLATE_PARMS
112 struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
114 static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
115 BOOST_FUNCTION_PARMS)
119 if (function_allows_small_object_optimization<FunctionObj>::value)
120 f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
122 f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
123 return (*f)(BOOST_FUNCTION_ARGS);
128 typename FunctionObj,
129 typename R BOOST_FUNCTION_COMMA
130 BOOST_FUNCTION_TEMPLATE_PARMS
132 struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
134 static BOOST_FUNCTION_VOID_RETURN_TYPE
135 invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
136 BOOST_FUNCTION_PARMS)
140 if (function_allows_small_object_optimization<FunctionObj>::value)
141 f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
143 f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
144 BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
149 typename FunctionObj,
150 typename R BOOST_FUNCTION_COMMA
151 BOOST_FUNCTION_TEMPLATE_PARMS
153 struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
155 static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
156 BOOST_FUNCTION_PARMS)
160 reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
161 return (*f)(BOOST_FUNCTION_ARGS);
166 typename FunctionObj,
167 typename R BOOST_FUNCTION_COMMA
168 BOOST_FUNCTION_TEMPLATE_PARMS
170 struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
172 static BOOST_FUNCTION_VOID_RETURN_TYPE
173 invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
174 BOOST_FUNCTION_PARMS)
178 reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
179 BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
184 typename FunctionPtr,
185 typename R BOOST_FUNCTION_COMMA
186 BOOST_FUNCTION_TEMPLATE_PARMS
188 struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
190 typedef typename mpl::if_c<(is_void<R>::value),
191 BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
193 R BOOST_FUNCTION_COMMA
194 BOOST_FUNCTION_TEMPLATE_ARGS
196 BOOST_FUNCTION_FUNCTION_INVOKER<
198 R BOOST_FUNCTION_COMMA
199 BOOST_FUNCTION_TEMPLATE_ARGS
205 typename FunctionObj,
206 typename R BOOST_FUNCTION_COMMA
207 BOOST_FUNCTION_TEMPLATE_PARMS
209 struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
211 typedef typename mpl::if_c<(is_void<R>::value),
212 BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
214 R BOOST_FUNCTION_COMMA
215 BOOST_FUNCTION_TEMPLATE_ARGS
217 BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
219 R BOOST_FUNCTION_COMMA
220 BOOST_FUNCTION_TEMPLATE_ARGS
226 typename FunctionObj,
227 typename R BOOST_FUNCTION_COMMA
228 BOOST_FUNCTION_TEMPLATE_PARMS
230 struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
232 typedef typename mpl::if_c<(is_void<R>::value),
233 BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
235 R BOOST_FUNCTION_COMMA
236 BOOST_FUNCTION_TEMPLATE_ARGS
238 BOOST_FUNCTION_FUNCTION_REF_INVOKER<
240 R BOOST_FUNCTION_COMMA
241 BOOST_FUNCTION_TEMPLATE_ARGS
247 * vtable for a specific boost::function instance.
249 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
250 struct BOOST_FUNCTION_VTABLE : vtable_base
252 #ifndef BOOST_NO_VOID_RETURNS
253 typedef R result_type;
255 typedef typename function_return_type<R>::type result_type;
256 #endif // BOOST_NO_VOID_RETURNS
258 typedef result_type (*invoker_type)(function_buffer&
260 BOOST_FUNCTION_TEMPLATE_ARGS);
263 BOOST_FUNCTION_VTABLE(F f) : vtable_base(), invoker(0)
267 template<typename F,typename Allocator>
268 BOOST_FUNCTION_VTABLE(F f, Allocator) : vtable_base(), invoker(0)
270 init_a<Allocator>(f);
274 bool assign_to(F f, function_buffer& functor)
276 typedef typename get_function_tag<F>::type tag;
277 return assign_to(f, functor, tag());
279 template<typename F,typename Allocator>
280 bool assign_to_a(F f, function_buffer& functor, Allocator a)
282 typedef typename get_function_tag<F>::type tag;
283 return assign_to_a(f, functor, a, tag());
286 void clear(function_buffer& functor)
289 manager(functor, functor, destroy_functor_tag);
296 typedef typename get_function_tag<F>::type tag;
299 template<typename Allocator,typename F>
302 typedef typename get_function_tag<F>::type tag;
303 init_a<Allocator>(f, tag());
307 template<typename FunctionPtr>
308 void init(FunctionPtr /*f*/, function_ptr_tag)
310 typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
312 R BOOST_FUNCTION_COMMA
313 BOOST_FUNCTION_TEMPLATE_ARGS
317 invoker = &actual_invoker_type::invoke;
318 manager = &functor_manager<FunctionPtr>::manage;
320 template<typename Allocator,typename FunctionPtr>
321 void init_a(FunctionPtr f, function_ptr_tag)
323 typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
325 R BOOST_FUNCTION_COMMA
326 BOOST_FUNCTION_TEMPLATE_ARGS
330 invoker = &actual_invoker_type::invoke;
331 manager = &functor_manager_a<FunctionPtr, Allocator>::manage;
334 template<typename FunctionPtr>
336 assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag)
338 this->clear(functor);
340 // should be a reinterpret cast, but some compilers insist
341 // on giving cv-qualifiers to free functions
342 functor.func_ptr = (void (*)())(f);
348 template<typename FunctionPtr,typename Allocator>
350 assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag)
352 return assign_to(f,functor,function_ptr_tag());
356 #if BOOST_FUNCTION_NUM_ARGS > 0
357 template<typename MemberPtr>
358 void init(MemberPtr f, member_ptr_tag)
360 // DPG TBD: Add explicit support for member function
361 // objects, so we invoke through mem_fn() but we retain the
362 // right target_type() values.
363 this->init(mem_fn(f));
365 template<typename Allocator,typename MemberPtr>
366 void init_a(MemberPtr f, member_ptr_tag)
368 // DPG TBD: Add explicit support for member function
369 // objects, so we invoke through mem_fn() but we retain the
370 // right target_type() values.
371 this->init_a<Allocator>(mem_fn(f));
374 template<typename MemberPtr>
375 bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag)
377 // DPG TBD: Add explicit support for member function
378 // objects, so we invoke through mem_fn() but we retain the
379 // right target_type() values.
381 this->assign_to(mem_fn(f), functor);
387 template<typename MemberPtr,typename Allocator>
388 bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag)
390 // DPG TBD: Add explicit support for member function
391 // objects, so we invoke through mem_fn() but we retain the
392 // right target_type() values.
394 this->assign_to_a(mem_fn(f), functor, a);
400 #endif // BOOST_FUNCTION_NUM_ARGS > 0
403 template<typename FunctionObj>
404 void init(FunctionObj /*f*/, function_obj_tag)
406 typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
408 R BOOST_FUNCTION_COMMA
409 BOOST_FUNCTION_TEMPLATE_ARGS
413 invoker = &actual_invoker_type::invoke;
414 manager = &functor_manager<FunctionObj>::manage;
416 template<typename Allocator,typename FunctionObj>
417 void init_a(FunctionObj /*f*/, function_obj_tag)
419 typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
421 R BOOST_FUNCTION_COMMA
422 BOOST_FUNCTION_TEMPLATE_ARGS
426 invoker = &actual_invoker_type::invoke;
427 manager = &functor_manager_a<FunctionObj, Allocator>::manage;
430 // Assign to a function object using the small object optimization
431 template<typename FunctionObj>
433 assign_functor(FunctionObj f, function_buffer& functor, mpl::true_)
435 new ((void*)&functor.data) FunctionObj(f);
437 template<typename FunctionObj,typename Allocator>
439 assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_)
441 assign_functor(f,functor,mpl::true_());
444 // Assign to a function object allocated on the heap.
445 template<typename FunctionObj>
447 assign_functor(FunctionObj f, function_buffer& functor, mpl::false_)
449 functor.obj_ptr = new FunctionObj(f);
451 template<typename FunctionObj,typename Allocator>
453 assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_)
455 typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
456 typedef typename Allocator::template rebind<functor_wrapper_type>::other
457 wrapper_allocator_type;
458 typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
459 wrapper_allocator_type wrapper_allocator(a);
460 wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
461 wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
462 functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
463 functor.obj_ptr = new_f;
466 template<typename FunctionObj>
468 assign_to(FunctionObj f, function_buffer& functor, function_obj_tag)
470 if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
471 assign_functor(f, functor,
472 mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
478 template<typename FunctionObj,typename Allocator>
480 assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag)
482 if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
483 assign_functor_a(f, functor, a,
484 mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
491 // Reference to a function object
492 template<typename FunctionObj>
494 init(const reference_wrapper<FunctionObj>& /*f*/, function_obj_ref_tag)
496 typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
498 R BOOST_FUNCTION_COMMA
499 BOOST_FUNCTION_TEMPLATE_ARGS
503 invoker = &actual_invoker_type::invoke;
504 manager = &reference_manager<FunctionObj>::get;
506 template<typename Allocator,typename FunctionObj>
508 init_a(const reference_wrapper<FunctionObj>& f, function_obj_ref_tag)
510 init(f,function_obj_ref_tag());
513 template<typename FunctionObj>
515 assign_to(const reference_wrapper<FunctionObj>& f,
516 function_buffer& functor, function_obj_ref_tag)
518 if (!boost::detail::function::has_empty_target(f.get_pointer())) {
519 // DPG TBD: We might need to detect constness of
520 // FunctionObj to assign into obj_ptr or const_obj_ptr to
521 // be truly legit, but no platform in existence makes
522 // const void* different from void*.
523 functor.const_obj_ptr = f.get_pointer();
529 template<typename FunctionObj,typename Allocator>
531 assign_to_a(const reference_wrapper<FunctionObj>& f,
532 function_buffer& functor, Allocator, function_obj_ref_tag)
534 return assign_to(f,functor,function_obj_ref_tag());
538 invoker_type invoker;
540 } // end namespace function
541 } // end namespace detail
544 typename R BOOST_FUNCTION_COMMA
545 BOOST_FUNCTION_TEMPLATE_PARMS
547 class BOOST_FUNCTION_FUNCTION : public function_base
549 #if BOOST_FUNCTION_NUM_ARGS == 1
551 , public std::unary_function<T0,R>
553 #elif BOOST_FUNCTION_NUM_ARGS == 2
555 , public std::binary_function<T0,T1,R>
561 #ifndef BOOST_NO_VOID_RETURNS
562 typedef R result_type;
564 typedef typename boost::detail::function::function_return_type<R>::type
566 #endif // BOOST_NO_VOID_RETURNS
569 typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
570 R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
573 struct clear_type {};
576 BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
578 // add signature for boost::lambda
579 template<typename Args>
582 typedef result_type type;
585 #if BOOST_FUNCTION_NUM_ARGS == 1
586 typedef T0 argument_type;
587 #elif BOOST_FUNCTION_NUM_ARGS == 2
588 typedef T0 first_argument_type;
589 typedef T1 second_argument_type;
592 BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
593 BOOST_FUNCTION_ARG_TYPES
595 typedef BOOST_FUNCTION_FUNCTION self_type;
597 BOOST_FUNCTION_FUNCTION() : function_base() { }
599 // MSVC chokes if the following two constructors are collapsed into
600 // one with a default parameter.
601 template<typename Functor>
602 BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
603 #ifndef BOOST_NO_SFINAE
604 ,typename enable_if_c<
605 (boost::type_traits::ice_not<
606 (is_integral<Functor>::value)>::value),
608 #endif // BOOST_NO_SFINAE
614 template<typename Functor,typename Allocator>
615 BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
616 #ifndef BOOST_NO_SFINAE
617 ,typename enable_if_c<
618 (boost::type_traits::ice_not<
619 (is_integral<Functor>::value)>::value),
621 #endif // BOOST_NO_SFINAE
625 this->assign_to_a(f,a);
628 #ifndef BOOST_NO_SFINAE
629 BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
631 BOOST_FUNCTION_FUNCTION(int zero) : function_base()
633 BOOST_ASSERT(zero == 0);
637 BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
639 this->assign_to_own(f);
642 ~BOOST_FUNCTION_FUNCTION() { clear(); }
644 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
645 // MSVC 6.0 and prior require all definitions to be inline, but
646 // these definitions can become very costly.
647 result_type operator()(BOOST_FUNCTION_PARMS) const
650 boost::throw_exception(bad_function_call());
652 return static_cast<vtable_type*>(vtable)->invoker
653 (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
656 result_type operator()(BOOST_FUNCTION_PARMS) const;
659 // The distinction between when to use BOOST_FUNCTION_FUNCTION and
660 // when to use self_type is obnoxious. MSVC cannot handle self_type as
661 // the return type of these assignment operators, but Borland C++ cannot
662 // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
664 template<typename Functor>
665 #ifndef BOOST_NO_SFINAE
666 typename enable_if_c<
667 (boost::type_traits::ice_not<
668 (is_integral<Functor>::value)>::value),
669 BOOST_FUNCTION_FUNCTION&>::type
671 BOOST_FUNCTION_FUNCTION&
673 operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
684 template<typename Functor,typename Allocator>
685 void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
689 this->assign_to_a(f,a);
696 #ifndef BOOST_NO_SFINAE
697 BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
703 BOOST_FUNCTION_FUNCTION& operator=(int zero)
705 BOOST_ASSERT(zero == 0);
711 // Assignment from another BOOST_FUNCTION_FUNCTION
712 BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
719 this->assign_to_own(f);
727 void swap(BOOST_FUNCTION_FUNCTION& other)
732 BOOST_FUNCTION_FUNCTION tmp = *this;
737 // Clear out a target, if there is one
741 static_cast<vtable_type*>(vtable)->clear(this->functor);
746 #if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
747 // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
748 operator bool () const { return !this->empty(); }
755 typedef void (dummy::*safe_bool)();
758 operator safe_bool () const
759 { return (this->empty())? 0 : &dummy::nonnull; }
761 bool operator!() const
762 { return this->empty(); }
766 void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
769 this->vtable = f.vtable;
770 f.vtable->manager(f.functor, this->functor,
771 boost::detail::function::clone_functor_tag);
775 template<typename Functor>
776 void assign_to(Functor f)
778 static vtable_type stored_vtable(f);
779 if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable;
782 template<typename Functor,typename Allocator>
783 void assign_to_a(Functor f,Allocator a)
785 static vtable_type stored_vtable(f,a);
786 if (stored_vtable.assign_to_a(f, functor, a)) vtable = &stored_vtable;
791 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
792 inline void swap(BOOST_FUNCTION_FUNCTION<
793 R BOOST_FUNCTION_COMMA
794 BOOST_FUNCTION_TEMPLATE_ARGS
796 BOOST_FUNCTION_FUNCTION<
797 R BOOST_FUNCTION_COMMA
798 BOOST_FUNCTION_TEMPLATE_ARGS
804 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
805 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
806 typename BOOST_FUNCTION_FUNCTION<
807 R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type
808 BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
809 ::operator()(BOOST_FUNCTION_PARMS) const
812 boost::throw_exception(bad_function_call());
814 return static_cast<vtable_type*>(vtable)->invoker
815 (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
819 // Poison comparisons between boost::function objects of the same type.
820 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
821 void operator==(const BOOST_FUNCTION_FUNCTION<
822 R BOOST_FUNCTION_COMMA
823 BOOST_FUNCTION_TEMPLATE_ARGS>&,
824 const BOOST_FUNCTION_FUNCTION<
825 R BOOST_FUNCTION_COMMA
826 BOOST_FUNCTION_TEMPLATE_ARGS>&);
827 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
828 void operator!=(const BOOST_FUNCTION_FUNCTION<
829 R BOOST_FUNCTION_COMMA
830 BOOST_FUNCTION_TEMPLATE_ARGS>&,
831 const BOOST_FUNCTION_FUNCTION<
832 R BOOST_FUNCTION_COMMA
833 BOOST_FUNCTION_TEMPLATE_ARGS>& );
835 #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
837 #if BOOST_FUNCTION_NUM_ARGS == 0
838 #define BOOST_FUNCTION_PARTIAL_SPEC R (void)
840 #define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
843 template<typename R BOOST_FUNCTION_COMMA
844 BOOST_FUNCTION_TEMPLATE_PARMS>
845 class function<BOOST_FUNCTION_PARTIAL_SPEC>
846 : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
848 typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
849 typedef function self_type;
851 struct clear_type {};
855 function() : base_type() {}
857 template<typename Functor>
859 #ifndef BOOST_NO_SFINAE
860 ,typename enable_if_c<
861 (boost::type_traits::ice_not<
862 (is_integral<Functor>::value)>::value),
869 template<typename Functor,typename Allocator>
870 function(Functor f, Allocator a
871 #ifndef BOOST_NO_SFINAE
872 ,typename enable_if_c<
873 (boost::type_traits::ice_not<
874 (is_integral<Functor>::value)>::value),
882 #ifndef BOOST_NO_SFINAE
883 function(clear_type*) : base_type() {}
886 function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
888 function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
890 self_type& operator=(const self_type& f)
892 self_type(f).swap(*this);
896 template<typename Functor>
897 #ifndef BOOST_NO_SFINAE
898 typename enable_if_c<
899 (boost::type_traits::ice_not<
900 (is_integral<Functor>::value)>::value),
907 self_type(f).swap(*this);
911 #ifndef BOOST_NO_SFINAE
912 self_type& operator=(clear_type*)
919 self_type& operator=(const base_type& f)
921 self_type(f).swap(*this);
926 #undef BOOST_FUNCTION_PARTIAL_SPEC
927 #endif // have partial specialization
929 } // end namespace boost
931 // Cleanup after ourselves...
932 #undef BOOST_FUNCTION_VTABLE
933 #undef BOOST_FUNCTION_COMMA
934 #undef BOOST_FUNCTION_FUNCTION
935 #undef BOOST_FUNCTION_FUNCTION_INVOKER
936 #undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
937 #undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
938 #undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
939 #undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
940 #undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
941 #undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
942 #undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
943 #undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
944 #undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
945 #undef BOOST_FUNCTION_TEMPLATE_PARMS
946 #undef BOOST_FUNCTION_TEMPLATE_ARGS
947 #undef BOOST_FUNCTION_PARMS
948 #undef BOOST_FUNCTION_PARM
949 #undef BOOST_FUNCTION_ARGS
950 #undef BOOST_FUNCTION_ARG_TYPE
951 #undef BOOST_FUNCTION_ARG_TYPES
952 #undef BOOST_FUNCTION_VOID_RETURN_TYPE
953 #undef BOOST_FUNCTION_RETURN
955 #if defined(BOOST_MSVC)
956 # pragma warning( pop )