Chris@16: // Boost.Function library Chris@16: Chris@16: // Copyright Douglas Gregor 2001-2006 Chris@16: // Copyright Emil Dotchevski 2007 Chris@16: // Use, modification and distribution is subject to the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // For more information, see http://www.boost.org Chris@16: Chris@16: // Note: this header is a header template and must NOT have multiple-inclusion Chris@16: // protection. Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_MSVC) Chris@16: # pragma warning( push ) Chris@16: # pragma warning( disable : 4127 ) // "conditional expression is constant" Chris@16: #endif Chris@16: Chris@16: #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T) Chris@16: Chris@16: #define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T) Chris@16: Chris@16: #define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I) Chris@16: Chris@16: #define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY) Chris@16: Chris@101: #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@101: # define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a) Chris@101: #else Chris@101: # include Chris@101: # define BOOST_FUNCTION_ARG(J,I,D) ::boost::forward< BOOST_PP_CAT(T,I) >(BOOST_PP_CAT(a,I)) Chris@101: # define BOOST_FUNCTION_ARGS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG,BOOST_PP_EMPTY) Chris@101: #endif Chris@16: Chris@16: #define BOOST_FUNCTION_ARG_TYPE(J,I,D) \ Chris@16: typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type); Chris@16: Chris@16: #define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY) Chris@16: Chris@16: // Comma if nonzero number of arguments Chris@16: #if BOOST_FUNCTION_NUM_ARGS == 0 Chris@16: # define BOOST_FUNCTION_COMMA Chris@16: #else Chris@16: # define BOOST_FUNCTION_COMMA , Chris@16: #endif // BOOST_FUNCTION_NUM_ARGS > 0 Chris@16: Chris@16: // Class names used in this version of the code Chris@16: #define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_FUNCTION_INVOKER \ Chris@16: BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \ Chris@16: BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \ Chris@16: BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \ Chris@16: BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_FUNCTION_REF_INVOKER \ Chris@16: BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \ Chris@16: BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_MEMBER_INVOKER \ Chris@16: BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_VOID_MEMBER_INVOKER \ Chris@16: BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_GET_FUNCTION_INVOKER \ Chris@16: BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \ Chris@16: BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \ Chris@16: BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_GET_MEMBER_INVOKER \ Chris@16: BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_GET_INVOKER \ Chris@16: BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS) Chris@16: #define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS) Chris@16: Chris@16: #ifndef BOOST_NO_VOID_RETURNS Chris@16: # define BOOST_FUNCTION_VOID_RETURN_TYPE void Chris@16: # define BOOST_FUNCTION_RETURN(X) X Chris@16: #else Chris@16: # define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable Chris@16: # define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE () Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: namespace detail { Chris@16: namespace function { Chris@16: template< Chris@16: typename FunctionPtr, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_FUNCTION_INVOKER Chris@16: { Chris@16: static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_PARMS) Chris@16: { Chris@16: FunctionPtr f = reinterpret_cast(function_ptr.func_ptr); Chris@16: return f(BOOST_FUNCTION_ARGS); Chris@16: } Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename FunctionPtr, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER Chris@16: { Chris@16: static BOOST_FUNCTION_VOID_RETURN_TYPE Chris@16: invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_PARMS) Chris@16: Chris@16: { Chris@16: FunctionPtr f = reinterpret_cast(function_ptr.func_ptr); Chris@16: BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS)); Chris@16: } Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename FunctionObj, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER Chris@16: { Chris@16: static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_PARMS) Chris@16: Chris@16: { Chris@16: FunctionObj* f; Chris@16: if (function_allows_small_object_optimization::value) Chris@16: f = reinterpret_cast(&function_obj_ptr.data); Chris@16: else Chris@16: f = reinterpret_cast(function_obj_ptr.obj_ptr); Chris@16: return (*f)(BOOST_FUNCTION_ARGS); Chris@16: } Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename FunctionObj, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER Chris@16: { Chris@16: static BOOST_FUNCTION_VOID_RETURN_TYPE Chris@16: invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_PARMS) Chris@16: Chris@16: { Chris@16: FunctionObj* f; Chris@16: if (function_allows_small_object_optimization::value) Chris@16: f = reinterpret_cast(&function_obj_ptr.data); Chris@16: else Chris@16: f = reinterpret_cast(function_obj_ptr.obj_ptr); Chris@16: BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); Chris@16: } Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename FunctionObj, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_FUNCTION_REF_INVOKER Chris@16: { Chris@16: static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_PARMS) Chris@16: Chris@16: { Chris@16: FunctionObj* f = Chris@16: reinterpret_cast(function_obj_ptr.obj_ptr); Chris@16: return (*f)(BOOST_FUNCTION_ARGS); Chris@16: } Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename FunctionObj, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER Chris@16: { Chris@16: static BOOST_FUNCTION_VOID_RETURN_TYPE Chris@16: invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_PARMS) Chris@16: Chris@16: { Chris@16: FunctionObj* f = Chris@16: reinterpret_cast(function_obj_ptr.obj_ptr); Chris@16: BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); Chris@16: } Chris@16: }; Chris@16: Chris@16: #if BOOST_FUNCTION_NUM_ARGS > 0 Chris@16: /* Handle invocation of member pointers. */ Chris@16: template< Chris@16: typename MemberPtr, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_MEMBER_INVOKER Chris@16: { Chris@16: static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_PARMS) Chris@16: Chris@16: { Chris@16: MemberPtr* f = Chris@16: reinterpret_cast(&function_obj_ptr.data); Chris@16: return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS); Chris@16: } Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename MemberPtr, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_VOID_MEMBER_INVOKER Chris@16: { Chris@16: static BOOST_FUNCTION_VOID_RETURN_TYPE Chris@16: invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_PARMS) Chris@16: Chris@16: { Chris@16: MemberPtr* f = Chris@16: reinterpret_cast(&function_obj_ptr.data); Chris@16: BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS)); Chris@16: } Chris@16: }; Chris@16: #endif Chris@16: Chris@16: template< Chris@16: typename FunctionPtr, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_GET_FUNCTION_INVOKER Chris@16: { Chris@16: typedef typename mpl::if_c<(is_void::value), Chris@16: BOOST_FUNCTION_VOID_FUNCTION_INVOKER< Chris@16: FunctionPtr, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >, Chris@16: BOOST_FUNCTION_FUNCTION_INVOKER< Chris@16: FunctionPtr, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: > Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename FunctionObj, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER Chris@16: { Chris@16: typedef typename mpl::if_c<(is_void::value), Chris@16: BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER< Chris@16: FunctionObj, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >, Chris@16: BOOST_FUNCTION_FUNCTION_OBJ_INVOKER< Chris@16: FunctionObj, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: > Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: template< Chris@16: typename FunctionObj, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER Chris@16: { Chris@16: typedef typename mpl::if_c<(is_void::value), Chris@16: BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER< Chris@16: FunctionObj, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >, Chris@16: BOOST_FUNCTION_FUNCTION_REF_INVOKER< Chris@16: FunctionObj, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: > Chris@16: >::type type; Chris@16: }; Chris@16: Chris@16: #if BOOST_FUNCTION_NUM_ARGS > 0 Chris@16: /* Retrieve the appropriate invoker for a member pointer. */ Chris@16: template< Chris@16: typename MemberPtr, Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: struct BOOST_FUNCTION_GET_MEMBER_INVOKER Chris@16: { Chris@16: typedef typename mpl::if_c<(is_void::value), Chris@16: BOOST_FUNCTION_VOID_MEMBER_INVOKER< Chris@16: MemberPtr, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >, Chris@16: BOOST_FUNCTION_MEMBER_INVOKER< Chris@16: MemberPtr, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: > Chris@16: >::type type; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: /* Given the tag returned by get_function_tag, retrieve the Chris@16: actual invoker that will be used for the given function Chris@16: object. Chris@16: Chris@16: Each specialization contains an "apply" nested class template Chris@16: that accepts the function object, return type, function Chris@16: argument types, and allocator. The resulting "apply" class Chris@16: contains two typedefs, "invoker_type" and "manager_type", Chris@16: which correspond to the invoker and manager types. */ Chris@16: template Chris@16: struct BOOST_FUNCTION_GET_INVOKER { }; Chris@16: Chris@16: /* Retrieve the invoker for a function pointer. */ Chris@16: template<> Chris@16: struct BOOST_FUNCTION_GET_INVOKER Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER< Chris@16: FunctionPtr, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >::type Chris@16: invoker_type; Chris@16: Chris@16: typedef functor_manager manager_type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct apply_a Chris@16: { Chris@16: typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER< Chris@16: FunctionPtr, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >::type Chris@16: invoker_type; Chris@16: Chris@16: typedef functor_manager manager_type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: #if BOOST_FUNCTION_NUM_ARGS > 0 Chris@16: /* Retrieve the invoker for a member pointer. */ Chris@16: template<> Chris@16: struct BOOST_FUNCTION_GET_INVOKER Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER< Chris@16: MemberPtr, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >::type Chris@16: invoker_type; Chris@16: Chris@16: typedef functor_manager manager_type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct apply_a Chris@16: { Chris@16: typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER< Chris@16: MemberPtr, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >::type Chris@16: invoker_type; Chris@16: Chris@16: typedef functor_manager manager_type; Chris@16: }; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: /* Retrieve the invoker for a function object. */ Chris@16: template<> Chris@16: struct BOOST_FUNCTION_GET_INVOKER Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER< Chris@16: FunctionObj, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >::type Chris@16: invoker_type; Chris@16: Chris@16: typedef functor_manager manager_type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct apply_a Chris@16: { Chris@16: typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER< Chris@16: FunctionObj, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >::type Chris@16: invoker_type; Chris@16: Chris@16: typedef functor_manager_a manager_type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: /* Retrieve the invoker for a reference to a function object. */ Chris@16: template<> Chris@16: struct BOOST_FUNCTION_GET_INVOKER Chris@16: { Chris@16: template Chris@16: struct apply Chris@16: { Chris@16: typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER< Chris@16: typename RefWrapper::type, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >::type Chris@16: invoker_type; Chris@16: Chris@16: typedef reference_manager manager_type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct apply_a Chris@16: { Chris@16: typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER< Chris@16: typename RefWrapper::type, Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >::type Chris@16: invoker_type; Chris@16: Chris@16: typedef reference_manager manager_type; Chris@16: }; Chris@16: }; Chris@16: Chris@16: Chris@16: /** Chris@16: * vtable for a specific boost::function instance. This Chris@16: * structure must be an aggregate so that we can use static Chris@16: * initialization in boost::function's assign_to and assign_to_a Chris@16: * members. It therefore cannot have any constructors, Chris@16: * destructors, base classes, etc. Chris@16: */ Chris@16: template Chris@16: struct BOOST_FUNCTION_VTABLE Chris@16: { Chris@16: #ifndef BOOST_NO_VOID_RETURNS Chris@16: typedef R result_type; Chris@16: #else Chris@16: typedef typename function_return_type::type result_type; Chris@16: #endif // BOOST_NO_VOID_RETURNS Chris@16: Chris@16: typedef result_type (*invoker_type)(function_buffer& Chris@16: BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS); Chris@16: Chris@16: template Chris@16: bool assign_to(F f, function_buffer& functor) const Chris@16: { Chris@16: typedef typename get_function_tag::type tag; Chris@16: return assign_to(f, functor, tag()); Chris@16: } Chris@16: template Chris@16: bool assign_to_a(F f, function_buffer& functor, Allocator a) const Chris@16: { Chris@16: typedef typename get_function_tag::type tag; Chris@16: return assign_to_a(f, functor, a, tag()); Chris@16: } Chris@16: Chris@16: void clear(function_buffer& functor) const Chris@16: { Chris@16: if (base.manager) Chris@16: base.manager(functor, functor, destroy_functor_tag); Chris@16: } Chris@16: Chris@16: private: Chris@16: // Function pointers Chris@16: template Chris@16: bool Chris@16: assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const Chris@16: { Chris@16: this->clear(functor); Chris@16: if (f) { Chris@16: // should be a reinterpret cast, but some compilers insist Chris@16: // on giving cv-qualifiers to free functions Chris@16: functor.func_ptr = reinterpret_cast(f); Chris@16: return true; Chris@16: } else { Chris@16: return false; Chris@16: } Chris@16: } Chris@16: template Chris@16: bool Chris@16: assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const Chris@16: { Chris@16: return assign_to(f,functor,function_ptr_tag()); Chris@16: } Chris@16: Chris@16: // Member pointers Chris@16: #if BOOST_FUNCTION_NUM_ARGS > 0 Chris@16: template Chris@16: bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const Chris@16: { Chris@16: // DPG TBD: Add explicit support for member function Chris@16: // objects, so we invoke through mem_fn() but we retain the Chris@16: // right target_type() values. Chris@16: if (f) { Chris@16: this->assign_to(boost::mem_fn(f), functor); Chris@16: return true; Chris@16: } else { Chris@16: return false; Chris@16: } Chris@16: } Chris@16: template Chris@16: bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const Chris@16: { Chris@16: // DPG TBD: Add explicit support for member function Chris@16: // objects, so we invoke through mem_fn() but we retain the Chris@16: // right target_type() values. Chris@16: if (f) { Chris@16: this->assign_to_a(boost::mem_fn(f), functor, a); Chris@16: return true; Chris@16: } else { Chris@16: return false; Chris@16: } Chris@16: } Chris@16: #endif // BOOST_FUNCTION_NUM_ARGS > 0 Chris@16: Chris@16: // Function objects Chris@16: // Assign to a function object using the small object optimization Chris@16: template Chris@16: void Chris@16: assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const Chris@16: { Chris@16: new (reinterpret_cast(&functor.data)) FunctionObj(f); Chris@16: } Chris@16: template Chris@16: void Chris@16: assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) const Chris@16: { Chris@16: assign_functor(f,functor,mpl::true_()); Chris@16: } Chris@16: Chris@16: // Assign to a function object allocated on the heap. Chris@16: template Chris@16: void Chris@16: assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) const Chris@16: { Chris@16: functor.obj_ptr = new FunctionObj(f); Chris@16: } Chris@16: template Chris@16: void Chris@16: assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const Chris@16: { Chris@16: typedef functor_wrapper functor_wrapper_type; Chris@16: typedef typename Allocator::template rebind::other Chris@16: wrapper_allocator_type; Chris@16: typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type; Chris@16: wrapper_allocator_type wrapper_allocator(a); Chris@16: wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1); Chris@16: wrapper_allocator.construct(copy, functor_wrapper_type(f,a)); Chris@16: functor_wrapper_type* new_f = static_cast(copy); Chris@16: functor.obj_ptr = new_f; Chris@16: } Chris@16: Chris@16: template Chris@16: bool Chris@16: assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const Chris@16: { Chris@16: if (!boost::detail::function::has_empty_target(boost::addressof(f))) { Chris@16: assign_functor(f, functor, Chris@16: mpl::bool_<(function_allows_small_object_optimization::value)>()); Chris@16: return true; Chris@16: } else { Chris@16: return false; Chris@16: } Chris@16: } Chris@16: template Chris@16: bool Chris@16: assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const Chris@16: { Chris@16: if (!boost::detail::function::has_empty_target(boost::addressof(f))) { Chris@16: assign_functor_a(f, functor, a, Chris@16: mpl::bool_<(function_allows_small_object_optimization::value)>()); Chris@16: return true; Chris@16: } else { Chris@16: return false; Chris@16: } Chris@16: } Chris@16: Chris@16: // Reference to a function object Chris@16: template Chris@16: bool Chris@16: assign_to(const reference_wrapper& f, Chris@16: function_buffer& functor, function_obj_ref_tag) const Chris@16: { Chris@16: functor.obj_ref.obj_ptr = (void *)(f.get_pointer()); Chris@16: functor.obj_ref.is_const_qualified = is_const::value; Chris@16: functor.obj_ref.is_volatile_qualified = is_volatile::value; Chris@16: return true; Chris@16: } Chris@16: template Chris@16: bool Chris@16: assign_to_a(const reference_wrapper& f, Chris@16: function_buffer& functor, Allocator, function_obj_ref_tag) const Chris@16: { Chris@16: return assign_to(f,functor,function_obj_ref_tag()); Chris@16: } Chris@16: Chris@16: public: Chris@16: vtable_base base; Chris@16: invoker_type invoker; Chris@16: }; Chris@16: } // end namespace function Chris@16: } // end namespace detail Chris@16: Chris@16: template< Chris@16: typename R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: > Chris@16: class BOOST_FUNCTION_FUNCTION : public function_base Chris@16: Chris@16: #if BOOST_FUNCTION_NUM_ARGS == 1 Chris@16: Chris@16: , public std::unary_function Chris@16: Chris@16: #elif BOOST_FUNCTION_NUM_ARGS == 2 Chris@16: Chris@16: , public std::binary_function Chris@16: Chris@16: #endif Chris@16: Chris@16: { Chris@16: public: Chris@16: #ifndef BOOST_NO_VOID_RETURNS Chris@16: typedef R result_type; Chris@16: #else Chris@16: typedef typename boost::detail::function::function_return_type::type Chris@16: result_type; Chris@16: #endif // BOOST_NO_VOID_RETURNS Chris@16: Chris@16: private: Chris@16: typedef boost::detail::function::BOOST_FUNCTION_VTABLE< Chris@16: R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> Chris@16: vtable_type; Chris@16: Chris@16: vtable_type* get_vtable() const { Chris@16: return reinterpret_cast( Chris@16: reinterpret_cast(vtable) & ~static_cast(0x01)); Chris@16: } Chris@16: Chris@16: struct clear_type {}; Chris@16: Chris@16: public: Chris@16: BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS); Chris@16: Chris@16: // add signature for boost::lambda Chris@16: template Chris@16: struct sig Chris@16: { Chris@16: typedef result_type type; Chris@16: }; Chris@16: Chris@16: #if BOOST_FUNCTION_NUM_ARGS == 1 Chris@16: typedef T0 argument_type; Chris@16: #elif BOOST_FUNCTION_NUM_ARGS == 2 Chris@16: typedef T0 first_argument_type; Chris@16: typedef T1 second_argument_type; Chris@16: #endif Chris@16: Chris@16: BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS); Chris@16: BOOST_FUNCTION_ARG_TYPES Chris@16: Chris@16: typedef BOOST_FUNCTION_FUNCTION self_type; Chris@16: Chris@16: BOOST_FUNCTION_FUNCTION() : function_base() { } Chris@16: Chris@16: // MSVC chokes if the following two constructors are collapsed into Chris@16: // one with a default parameter. Chris@16: template Chris@16: BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f Chris@16: #ifndef BOOST_NO_SFINAE Chris@16: ,typename enable_if_c< Chris@16: (boost::type_traits::ice_not< Chris@16: (is_integral::value)>::value), Chris@16: int>::type = 0 Chris@16: #endif // BOOST_NO_SFINAE Chris@16: ) : Chris@16: function_base() Chris@16: { Chris@16: this->assign_to(f); Chris@16: } Chris@16: template Chris@16: BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a Chris@16: #ifndef BOOST_NO_SFINAE Chris@16: ,typename enable_if_c< Chris@16: (boost::type_traits::ice_not< Chris@16: (is_integral::value)>::value), Chris@16: int>::type = 0 Chris@16: #endif // BOOST_NO_SFINAE Chris@16: ) : Chris@16: function_base() Chris@16: { Chris@16: this->assign_to_a(f,a); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_SFINAE Chris@16: BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { } Chris@16: #else Chris@16: BOOST_FUNCTION_FUNCTION(int zero) : function_base() Chris@16: { Chris@16: BOOST_ASSERT(zero == 0); Chris@16: } Chris@16: #endif Chris@16: Chris@16: BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base() Chris@16: { Chris@16: this->assign_to_own(f); Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base() Chris@16: { Chris@16: this->move_assign(f); Chris@16: } Chris@16: #endif Chris@16: Chris@16: ~BOOST_FUNCTION_FUNCTION() { clear(); } Chris@16: Chris@16: result_type operator()(BOOST_FUNCTION_PARMS) const Chris@16: { Chris@16: if (this->empty()) Chris@16: boost::throw_exception(bad_function_call()); Chris@16: Chris@16: return get_vtable()->invoker Chris@16: (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); Chris@16: } Chris@16: Chris@16: // The distinction between when to use BOOST_FUNCTION_FUNCTION and Chris@16: // when to use self_type is obnoxious. MSVC cannot handle self_type as Chris@16: // the return type of these assignment operators, but Borland C++ cannot Chris@16: // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to Chris@16: // construct. Chris@16: template Chris@16: #ifndef BOOST_NO_SFINAE Chris@16: typename enable_if_c< Chris@16: (boost::type_traits::ice_not< Chris@16: (is_integral::value)>::value), Chris@16: BOOST_FUNCTION_FUNCTION&>::type Chris@16: #else Chris@16: BOOST_FUNCTION_FUNCTION& Chris@16: #endif Chris@16: operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) Chris@16: { Chris@16: this->clear(); Chris@16: BOOST_TRY { Chris@16: this->assign_to(f); Chris@16: } BOOST_CATCH (...) { Chris@16: vtable = 0; Chris@16: BOOST_RETHROW; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: return *this; Chris@16: } Chris@16: template Chris@16: void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a) Chris@16: { Chris@16: this->clear(); Chris@16: BOOST_TRY{ Chris@16: this->assign_to_a(f,a); Chris@16: } BOOST_CATCH (...) { Chris@16: vtable = 0; Chris@16: BOOST_RETHROW; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_SFINAE Chris@16: BOOST_FUNCTION_FUNCTION& operator=(clear_type*) Chris@16: { Chris@16: this->clear(); Chris@16: return *this; Chris@16: } Chris@16: #else Chris@16: BOOST_FUNCTION_FUNCTION& operator=(int zero) Chris@16: { Chris@16: BOOST_ASSERT(zero == 0); Chris@16: this->clear(); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: Chris@16: // Assignment from another BOOST_FUNCTION_FUNCTION Chris@16: BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f) Chris@16: { Chris@16: if (&f == this) Chris@16: return *this; Chris@16: Chris@16: this->clear(); Chris@16: BOOST_TRY { Chris@16: this->assign_to_own(f); Chris@16: } BOOST_CATCH (...) { Chris@16: vtable = 0; Chris@16: BOOST_RETHROW; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: return *this; Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: // Move assignment from another BOOST_FUNCTION_FUNCTION Chris@16: BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f) Chris@16: { Chris@16: Chris@16: if (&f == this) Chris@16: return *this; Chris@16: Chris@16: this->clear(); Chris@16: BOOST_TRY { Chris@16: this->move_assign(f); Chris@16: } BOOST_CATCH (...) { Chris@16: vtable = 0; Chris@16: BOOST_RETHROW; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: Chris@16: void swap(BOOST_FUNCTION_FUNCTION& other) Chris@16: { Chris@16: if (&other == this) Chris@16: return; Chris@16: Chris@16: BOOST_FUNCTION_FUNCTION tmp; Chris@16: tmp.move_assign(*this); Chris@16: this->move_assign(other); Chris@16: other.move_assign(tmp); Chris@16: } Chris@16: Chris@16: // Clear out a target, if there is one Chris@16: void clear() Chris@16: { Chris@16: if (vtable) { Chris@16: if (!this->has_trivial_copy_and_destroy()) Chris@16: get_vtable()->clear(this->functor); Chris@16: vtable = 0; Chris@16: } Chris@16: } Chris@16: Chris@16: #if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG) Chris@16: // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it Chris@16: operator bool () const { return !this->empty(); } Chris@16: #else Chris@16: private: Chris@16: struct dummy { Chris@16: void nonnull() {} Chris@16: }; Chris@16: Chris@16: typedef void (dummy::*safe_bool)(); Chris@16: Chris@16: public: Chris@16: operator safe_bool () const Chris@16: { return (this->empty())? 0 : &dummy::nonnull; } Chris@16: Chris@16: bool operator!() const Chris@16: { return this->empty(); } Chris@16: #endif Chris@16: Chris@16: private: Chris@16: void assign_to_own(const BOOST_FUNCTION_FUNCTION& f) Chris@16: { Chris@16: if (!f.empty()) { Chris@16: this->vtable = f.vtable; Chris@16: if (this->has_trivial_copy_and_destroy()) Chris@16: this->functor = f.functor; Chris@16: else Chris@16: get_vtable()->base.manager(f.functor, this->functor, Chris@16: boost::detail::function::clone_functor_tag); Chris@16: } Chris@16: } Chris@16: Chris@16: template Chris@16: void assign_to(Functor f) Chris@16: { Chris@101: using boost::detail::function::vtable_base; Chris@16: Chris@101: typedef typename boost::detail::function::get_function_tag::type tag; Chris@101: typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER get_invoker; Chris@16: typedef typename get_invoker:: Chris@16: template apply Chris@16: handler_type; Chris@16: Chris@16: typedef typename handler_type::invoker_type invoker_type; Chris@16: typedef typename handler_type::manager_type manager_type; Chris@16: Chris@16: // Note: it is extremely important that this initialization use Chris@16: // static initialization. Otherwise, we will have a race Chris@16: // condition here in multi-threaded code. See Chris@16: // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. Chris@16: static const vtable_type stored_vtable = Chris@16: { { &manager_type::manage }, &invoker_type::invoke }; Chris@16: Chris@16: if (stored_vtable.assign_to(f, functor)) { Chris@16: std::size_t value = reinterpret_cast(&stored_vtable.base); Chris@101: // coverity[pointless_expression]: suppress coverity warnings on apparant if(const). Chris@16: if (boost::has_trivial_copy_constructor::value && Chris@16: boost::has_trivial_destructor::value && Chris@101: boost::detail::function::function_allows_small_object_optimization::value) Chris@101: value |= static_cast(0x01); Chris@101: vtable = reinterpret_cast(value); Chris@16: } else Chris@16: vtable = 0; Chris@16: } Chris@16: Chris@16: template Chris@16: void assign_to_a(Functor f,Allocator a) Chris@16: { Chris@101: using boost::detail::function::vtable_base; Chris@16: Chris@101: typedef typename boost::detail::function::get_function_tag::type tag; Chris@101: typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER get_invoker; Chris@16: typedef typename get_invoker:: Chris@16: template apply_a Chris@16: handler_type; Chris@16: Chris@16: typedef typename handler_type::invoker_type invoker_type; Chris@16: typedef typename handler_type::manager_type manager_type; Chris@16: Chris@16: // Note: it is extremely important that this initialization use Chris@16: // static initialization. Otherwise, we will have a race Chris@16: // condition here in multi-threaded code. See Chris@16: // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. Chris@16: static const vtable_type stored_vtable = Chris@16: { { &manager_type::manage }, &invoker_type::invoke }; Chris@16: Chris@16: if (stored_vtable.assign_to_a(f, functor, a)) { Chris@16: std::size_t value = reinterpret_cast(&stored_vtable.base); Chris@101: // coverity[pointless_expression]: suppress coverity warnings on apparant if(const). Chris@16: if (boost::has_trivial_copy_constructor::value && Chris@16: boost::has_trivial_destructor::value && Chris@101: boost::detail::function::function_allows_small_object_optimization::value) Chris@16: value |= static_cast(0x01); Chris@101: vtable = reinterpret_cast(value); Chris@16: } else Chris@16: vtable = 0; Chris@16: } Chris@16: Chris@16: // Moves the value from the specified argument to *this. If the argument Chris@16: // has its function object allocated on the heap, move_assign will pass Chris@16: // its buffer to *this, and set the argument's buffer pointer to NULL. Chris@16: void move_assign(BOOST_FUNCTION_FUNCTION& f) Chris@16: { Chris@16: if (&f == this) Chris@16: return; Chris@16: Chris@16: BOOST_TRY { Chris@16: if (!f.empty()) { Chris@16: this->vtable = f.vtable; Chris@16: if (this->has_trivial_copy_and_destroy()) Chris@16: this->functor = f.functor; Chris@16: else Chris@16: get_vtable()->base.manager(f.functor, this->functor, Chris@16: boost::detail::function::move_functor_tag); Chris@16: f.vtable = 0; Chris@16: } else { Chris@16: clear(); Chris@16: } Chris@16: } BOOST_CATCH (...) { Chris@16: vtable = 0; Chris@16: BOOST_RETHROW; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: inline void swap(BOOST_FUNCTION_FUNCTION< Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >& f1, Chris@16: BOOST_FUNCTION_FUNCTION< Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: >& f2) Chris@16: { Chris@16: f1.swap(f2); Chris@16: } Chris@16: Chris@16: // Poison comparisons between boost::function objects of the same type. Chris@16: template Chris@16: void operator==(const BOOST_FUNCTION_FUNCTION< Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS>&, Chris@16: const BOOST_FUNCTION_FUNCTION< Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS>&); Chris@16: template Chris@16: void operator!=(const BOOST_FUNCTION_FUNCTION< Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS>&, Chris@16: const BOOST_FUNCTION_FUNCTION< Chris@16: R BOOST_FUNCTION_COMMA Chris@16: BOOST_FUNCTION_TEMPLATE_ARGS>& ); Chris@16: Chris@16: #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) Chris@16: Chris@16: #if BOOST_FUNCTION_NUM_ARGS == 0 Chris@16: #define BOOST_FUNCTION_PARTIAL_SPEC R (void) Chris@16: #else Chris@16: #define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T)) Chris@16: #endif Chris@16: Chris@16: template Chris@16: class function Chris@16: : public BOOST_FUNCTION_FUNCTION Chris@16: { Chris@16: typedef BOOST_FUNCTION_FUNCTION base_type; Chris@16: typedef function self_type; Chris@16: Chris@16: struct clear_type {}; Chris@16: Chris@16: public: Chris@16: Chris@16: function() : base_type() {} Chris@16: Chris@16: template Chris@16: function(Functor f Chris@16: #ifndef BOOST_NO_SFINAE Chris@16: ,typename enable_if_c< Chris@16: (boost::type_traits::ice_not< Chris@16: (is_integral::value)>::value), Chris@16: int>::type = 0 Chris@16: #endif Chris@16: ) : Chris@16: base_type(f) Chris@16: { Chris@16: } Chris@16: template Chris@16: function(Functor f, Allocator a Chris@16: #ifndef BOOST_NO_SFINAE Chris@16: ,typename enable_if_c< Chris@16: (boost::type_traits::ice_not< Chris@16: (is_integral::value)>::value), Chris@16: int>::type = 0 Chris@16: #endif Chris@16: ) : Chris@16: base_type(f,a) Chris@16: { Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_SFINAE Chris@16: function(clear_type*) : base_type() {} Chris@16: #endif Chris@16: Chris@16: function(const self_type& f) : base_type(static_cast(f)){} Chris@16: Chris@16: function(const base_type& f) : base_type(static_cast(f)){} Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: // Move constructors Chris@16: function(self_type&& f): base_type(static_cast(f)){} Chris@16: function(base_type&& f): base_type(static_cast(f)){} Chris@16: #endif Chris@16: Chris@16: self_type& operator=(const self_type& f) Chris@16: { Chris@16: self_type(f).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: self_type& operator=(self_type&& f) Chris@16: { Chris@16: self_type(static_cast(f)).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: Chris@16: template Chris@16: #ifndef BOOST_NO_SFINAE Chris@16: typename enable_if_c< Chris@16: (boost::type_traits::ice_not< Chris@16: (is_integral::value)>::value), Chris@16: self_type&>::type Chris@16: #else Chris@16: self_type& Chris@16: #endif Chris@16: operator=(Functor f) Chris@16: { Chris@16: self_type(f).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_SFINAE Chris@16: self_type& operator=(clear_type*) Chris@16: { Chris@16: this->clear(); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: Chris@16: self_type& operator=(const base_type& f) Chris@16: { Chris@16: self_type(f).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: self_type& operator=(base_type&& f) Chris@16: { Chris@16: self_type(static_cast(f)).swap(*this); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: }; Chris@16: Chris@16: #undef BOOST_FUNCTION_PARTIAL_SPEC Chris@16: #endif // have partial specialization Chris@16: Chris@16: } // end namespace boost Chris@16: Chris@16: // Cleanup after ourselves... Chris@16: #undef BOOST_FUNCTION_VTABLE Chris@16: #undef BOOST_FUNCTION_COMMA Chris@16: #undef BOOST_FUNCTION_FUNCTION Chris@16: #undef BOOST_FUNCTION_FUNCTION_INVOKER Chris@16: #undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER Chris@16: #undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER Chris@16: #undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER Chris@16: #undef BOOST_FUNCTION_FUNCTION_REF_INVOKER Chris@16: #undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER Chris@16: #undef BOOST_FUNCTION_MEMBER_INVOKER Chris@16: #undef BOOST_FUNCTION_VOID_MEMBER_INVOKER Chris@16: #undef BOOST_FUNCTION_GET_FUNCTION_INVOKER Chris@16: #undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER Chris@16: #undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER Chris@16: #undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER Chris@16: #undef BOOST_FUNCTION_GET_INVOKER Chris@16: #undef BOOST_FUNCTION_TEMPLATE_PARMS Chris@16: #undef BOOST_FUNCTION_TEMPLATE_ARGS Chris@16: #undef BOOST_FUNCTION_PARMS Chris@16: #undef BOOST_FUNCTION_PARM Chris@101: #ifdef BOOST_FUNCTION_ARG Chris@101: # undef BOOST_FUNCTION_ARG Chris@101: #endif Chris@16: #undef BOOST_FUNCTION_ARGS Chris@16: #undef BOOST_FUNCTION_ARG_TYPE Chris@16: #undef BOOST_FUNCTION_ARG_TYPES Chris@16: #undef BOOST_FUNCTION_VOID_RETURN_TYPE Chris@16: #undef BOOST_FUNCTION_RETURN Chris@16: Chris@16: #if defined(BOOST_MSVC) Chris@16: # pragma warning( pop ) Chris@16: #endif