📄 function_template.hpp
字号:
// Boost.Function library// Copyright Douglas Gregor 2001-2003. Use, modification and// distribution is subject to the Boost Software License, Version// 1.0. (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)// For more information, see http://www.boost.org// Note: this header is a header template and must NOT have multiple-inclusion// protection.#include <boost/function/detail/prologue.hpp>#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)#define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)#define BOOST_FUNCTION_ARG_TYPE(J,I,D) \ typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(arg, BOOST_PP_CAT(BOOST_PP_INC(I),_type));#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)// Type of the default allocator#ifndef BOOST_NO_STD_ALLOCATOR# define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator<function_base>#else# define BOOST_FUNCTION_DEFAULT_ALLOCATOR int#endif // BOOST_NO_STD_ALLOCATOR// Comma if nonzero number of arguments#if BOOST_FUNCTION_NUM_ARGS == 0# define BOOST_FUNCTION_COMMA#else# define BOOST_FUNCTION_COMMA ,#endif // BOOST_FUNCTION_NUM_ARGS > 0// Class names used in this version of the code#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)#define BOOST_FUNCTION_FUNCTION_INVOKER \ BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \ BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \ BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \ BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)#define BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER \ BOOST_JOIN(stateless_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)#define BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER \ BOOST_JOIN(stateless_void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \ BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \ BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)#define BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER \ BOOST_JOIN(get_stateless_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)namespace boost { namespace detail { namespace function { template< typename FunctionPtr, typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS > struct BOOST_FUNCTION_FUNCTION_INVOKER { static R invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA BOOST_FUNCTION_PARMS) { FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr); return f(BOOST_FUNCTION_ARGS); } }; template< typename FunctionPtr, typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS > struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER { static unusable invoke(any_pointer function_ptr BOOST_FUNCTION_COMMA BOOST_FUNCTION_PARMS) { FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr); f(BOOST_FUNCTION_ARGS); return unusable(); } }; template< typename FunctionObj, typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS > struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER { static R invoke(any_pointer function_obj_ptr BOOST_FUNCTION_COMMA BOOST_FUNCTION_PARMS) { FunctionObj* f = (FunctionObj*)(function_obj_ptr.obj_ptr); return (*f)(BOOST_FUNCTION_ARGS); } }; template< typename FunctionObj, typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS > struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER { static unusable invoke(any_pointer function_obj_ptr BOOST_FUNCTION_COMMA BOOST_FUNCTION_PARMS) { FunctionObj* f = (FunctionObj*)(function_obj_ptr.obj_ptr); (*f)(BOOST_FUNCTION_ARGS); return unusable(); } }; template< typename FunctionObj, typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS > struct BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER { static R invoke(any_pointer BOOST_FUNCTION_COMMA BOOST_FUNCTION_PARMS) { FunctionObj f = FunctionObj(); return f(BOOST_FUNCTION_ARGS); } }; template< typename FunctionObj, typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS > struct BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER { static unusable invoke(any_pointer BOOST_FUNCTION_COMMA BOOST_FUNCTION_PARMS) { FunctionObj f = FunctionObj(); f(BOOST_FUNCTION_ARGS); return unusable(); } }; template< typename FunctionPtr, typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS > struct BOOST_FUNCTION_GET_FUNCTION_INVOKER { typedef typename ct_if<(is_void<R>::value), BOOST_FUNCTION_VOID_FUNCTION_INVOKER< FunctionPtr, R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS >, BOOST_FUNCTION_FUNCTION_INVOKER< FunctionPtr, R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS > >::type type; }; template< typename FunctionObj, typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS > struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER { typedef typename ct_if<(is_void<R>::value), BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER< FunctionObj, R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS >, BOOST_FUNCTION_FUNCTION_OBJ_INVOKER< FunctionObj, R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS > >::type type; }; template< typename FunctionObj, typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS > struct BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER { typedef typename ct_if<(is_void<R>::value), BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER< FunctionObj, R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS >, BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER< FunctionObj, R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS > >::type type; }; } // end namespace function } // end namespace detail template< typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS, typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR > class BOOST_FUNCTION_FUNCTION : public function_base { public: typedef typename detail::function::function_return_type<R>::type internal_result_type; private: struct clear_type {}; public: BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS); // add signature for boost::lambda template<typename Args> struct sig { typedef internal_result_type type; };#if BOOST_FUNCTION_NUM_ARGS == 1 typedef T0 argument_type;#elif BOOST_FUNCTION_NUM_ARGS == 2 typedef T0 first_argument_type; typedef T1 second_argument_type;#endif BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS); BOOST_FUNCTION_ARG_TYPES#ifndef BOOST_NO_VOID_RETURNS typedef R result_type;#else typedef internal_result_type result_type;#endif // BOOST_NO_VOID_RETURNS typedef Allocator allocator_type; typedef BOOST_FUNCTION_FUNCTION self_type; BOOST_FUNCTION_FUNCTION() : function_base() , invoker(0) {} // MSVC chokes if the following two constructors are collapsed into // one with a default parameter. template<typename Functor> BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f#ifndef BOOST_NO_SFINAE ,typename enable_if_c< (::boost::type_traits::ice_not< (is_integral<Functor>::value)>::value), int>::type = 0#endif // BOOST_NO_SFINAE ) : function_base(), invoker(0) { this->assign_to(f); }#ifndef BOOST_NO_SFINAE BOOST_FUNCTION_FUNCTION(clear_type*) : function_base(), invoker(0) {}#else BOOST_FUNCTION_FUNCTION(int zero) : function_base(), invoker(0) { BOOST_ASSERT(zero == 0); }#endif BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base(), invoker(0) { this->assign_to_own(f); } ~BOOST_FUNCTION_FUNCTION() { clear(); }#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // MSVC 6.0 and prior require all definitions to be inline, but // these definitions can become very costly. result_type operator()(BOOST_FUNCTION_PARMS) const { if (this->empty()) boost::throw_exception(bad_function_call()); internal_result_type result = invoker(this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);#ifndef BOOST_NO_VOID_RETURNS return static_cast<result_type>(result);#else return result;#endif // BOOST_NO_VOID_RETURNS }#else result_type operator()(BOOST_FUNCTION_PARMS) const;#endif // The distinction between when to use BOOST_FUNCTION_FUNCTION and // when to use self_type is obnoxious. MSVC cannot handle self_type as // the return type of these assignment operators, but Borland C++ cannot // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to // construct. template<typename Functor>#ifndef BOOST_NO_SFINAE typename enable_if_c< (::boost::type_traits::ice_not< (is_integral<Functor>::value)>::value), BOOST_FUNCTION_FUNCTION&>::type#else BOOST_FUNCTION_FUNCTION&#endif operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) { self_type(f).swap(*this); return *this; }#ifndef BOOST_NO_SFINAE BOOST_FUNCTION_FUNCTION& operator=(clear_type*) { this->clear(); return *this; }#else BOOST_FUNCTION_FUNCTION& operator=(int zero) { BOOST_ASSERT(zero == 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -