Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:55

0001 // Boost.Function library
0002 
0003 //  Copyright Douglas Gregor 2001-2006
0004 //  Copyright Emil Dotchevski 2007
0005 //  Use, modification and distribution is subject to the Boost Software License, Version 1.0.
0006 //  (See accompanying file LICENSE_1_0.txt or copy at
0007 //  http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 // For more information, see http://www.boost.org
0010 
0011 // Note: this header is a header template and must NOT have multiple-inclusion
0012 // protection.
0013 #include <boost/function/detail/prologue.hpp>
0014 #include <boost/core/no_exceptions_support.hpp>
0015 
0016 #if defined(BOOST_MSVC)
0017 #   pragma warning( push )
0018 #   pragma warning( disable : 4127 ) // "conditional expression is constant"
0019 #endif
0020 
0021 #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
0022 
0023 #define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
0024 
0025 #define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
0026 
0027 #define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
0028 
0029 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0030 #   define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
0031 #else
0032 #   define BOOST_FUNCTION_ARG(J,I,D) static_cast<BOOST_PP_CAT(T,I)&&>(BOOST_PP_CAT(a,I))
0033 #   define BOOST_FUNCTION_ARGS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG,BOOST_PP_EMPTY)
0034 #endif
0035 
0036 #define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
0037   typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
0038 
0039 #define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
0040 
0041 // Comma if nonzero number of arguments
0042 #if BOOST_FUNCTION_NUM_ARGS == 0
0043 #  define BOOST_FUNCTION_COMMA
0044 #else
0045 #  define BOOST_FUNCTION_COMMA ,
0046 #endif // BOOST_FUNCTION_NUM_ARGS > 0
0047 
0048 // Class names used in this version of the code
0049 #define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
0050 #define BOOST_FUNCTION_FUNCTION_INVOKER \
0051   BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
0052 #define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
0053   BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
0054 #define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
0055   BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
0056 #define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
0057   BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
0058 #define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
0059   BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
0060 #define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
0061   BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
0062 #define BOOST_FUNCTION_MEMBER_INVOKER \
0063   BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
0064 #define BOOST_FUNCTION_VOID_MEMBER_INVOKER \
0065   BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
0066 #define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
0067   BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
0068 #define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
0069   BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
0070 #define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
0071   BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
0072 #define BOOST_FUNCTION_GET_MEMBER_INVOKER \
0073   BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS)
0074 #define BOOST_FUNCTION_GET_INVOKER \
0075   BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS)
0076 #define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
0077 
0078 #ifndef BOOST_NO_VOID_RETURNS
0079 #  define BOOST_FUNCTION_VOID_RETURN_TYPE void
0080 #  define BOOST_FUNCTION_RETURN(X) X
0081 #else
0082 #  define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
0083 #  define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
0084 #endif
0085 
0086 namespace boost {
0087   namespace detail {
0088     namespace function {
0089       template<
0090         typename FunctionPtr,
0091         typename R BOOST_FUNCTION_COMMA
0092         BOOST_FUNCTION_TEMPLATE_PARMS
0093         >
0094       struct BOOST_FUNCTION_FUNCTION_INVOKER
0095       {
0096         static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
0097                         BOOST_FUNCTION_PARMS)
0098         {
0099           FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.members.func_ptr);
0100           return f(BOOST_FUNCTION_ARGS);
0101         }
0102       };
0103 
0104       template<
0105         typename FunctionPtr,
0106         typename R BOOST_FUNCTION_COMMA
0107         BOOST_FUNCTION_TEMPLATE_PARMS
0108         >
0109       struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
0110       {
0111         static BOOST_FUNCTION_VOID_RETURN_TYPE
0112         invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
0113                BOOST_FUNCTION_PARMS)
0114 
0115         {
0116           FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.members.func_ptr);
0117           BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
0118         }
0119       };
0120 
0121       template<
0122         typename FunctionObj,
0123         typename R BOOST_FUNCTION_COMMA
0124         BOOST_FUNCTION_TEMPLATE_PARMS
0125       >
0126       struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
0127       {
0128         static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
0129                         BOOST_FUNCTION_PARMS)
0130 
0131         {
0132           FunctionObj* f;
0133           if (function_allows_small_object_optimization<FunctionObj>::value)
0134             f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
0135           else
0136             f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
0137           return (*f)(BOOST_FUNCTION_ARGS);
0138         }
0139       };
0140 
0141       template<
0142         typename FunctionObj,
0143         typename R BOOST_FUNCTION_COMMA
0144         BOOST_FUNCTION_TEMPLATE_PARMS
0145       >
0146       struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
0147       {
0148         static BOOST_FUNCTION_VOID_RETURN_TYPE
0149         invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
0150                BOOST_FUNCTION_PARMS)
0151 
0152         {
0153           FunctionObj* f;
0154           if (function_allows_small_object_optimization<FunctionObj>::value)
0155             f = reinterpret_cast<FunctionObj*>(function_obj_ptr.data);
0156           else
0157             f = reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
0158           BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
0159         }
0160       };
0161 
0162       template<
0163         typename FunctionObj,
0164         typename R BOOST_FUNCTION_COMMA
0165         BOOST_FUNCTION_TEMPLATE_PARMS
0166       >
0167       struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
0168       {
0169         static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
0170                         BOOST_FUNCTION_PARMS)
0171 
0172         {
0173           FunctionObj* f =
0174             reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
0175           return (*f)(BOOST_FUNCTION_ARGS);
0176         }
0177       };
0178 
0179       template<
0180         typename FunctionObj,
0181         typename R BOOST_FUNCTION_COMMA
0182         BOOST_FUNCTION_TEMPLATE_PARMS
0183       >
0184       struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
0185       {
0186         static BOOST_FUNCTION_VOID_RETURN_TYPE
0187         invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
0188                BOOST_FUNCTION_PARMS)
0189 
0190         {
0191           FunctionObj* f =
0192             reinterpret_cast<FunctionObj*>(function_obj_ptr.members.obj_ptr);
0193           BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
0194         }
0195       };
0196 
0197 #if BOOST_FUNCTION_NUM_ARGS > 0
0198       /* Handle invocation of member pointers. */
0199       template<
0200         typename MemberPtr,
0201         typename R BOOST_FUNCTION_COMMA
0202         BOOST_FUNCTION_TEMPLATE_PARMS
0203       >
0204       struct BOOST_FUNCTION_MEMBER_INVOKER
0205       {
0206         static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
0207                         BOOST_FUNCTION_PARMS)
0208 
0209         {
0210           MemberPtr* f =
0211             reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
0212           return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
0213         }
0214       };
0215 
0216       template<
0217         typename MemberPtr,
0218         typename R BOOST_FUNCTION_COMMA
0219         BOOST_FUNCTION_TEMPLATE_PARMS
0220       >
0221       struct BOOST_FUNCTION_VOID_MEMBER_INVOKER
0222       {
0223         static BOOST_FUNCTION_VOID_RETURN_TYPE
0224         invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
0225                BOOST_FUNCTION_PARMS)
0226 
0227         {
0228           MemberPtr* f =
0229             reinterpret_cast<MemberPtr*>(function_obj_ptr.data);
0230           BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
0231         }
0232       };
0233 #endif
0234 
0235       template<
0236         typename FunctionPtr,
0237         typename R BOOST_FUNCTION_COMMA
0238         BOOST_FUNCTION_TEMPLATE_PARMS
0239       >
0240       struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
0241       {
0242         typedef typename conditional<(is_void<R>::value),
0243                             BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
0244                             FunctionPtr,
0245                             R BOOST_FUNCTION_COMMA
0246                             BOOST_FUNCTION_TEMPLATE_ARGS
0247                           >,
0248                           BOOST_FUNCTION_FUNCTION_INVOKER<
0249                             FunctionPtr,
0250                             R BOOST_FUNCTION_COMMA
0251                             BOOST_FUNCTION_TEMPLATE_ARGS
0252                           >
0253                        >::type type;
0254       };
0255 
0256       template<
0257         typename FunctionObj,
0258         typename R BOOST_FUNCTION_COMMA
0259         BOOST_FUNCTION_TEMPLATE_PARMS
0260        >
0261       struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
0262       {
0263         typedef typename conditional<(is_void<R>::value),
0264                             BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
0265                             FunctionObj,
0266                             R BOOST_FUNCTION_COMMA
0267                             BOOST_FUNCTION_TEMPLATE_ARGS
0268                           >,
0269                           BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
0270                             FunctionObj,
0271                             R BOOST_FUNCTION_COMMA
0272                             BOOST_FUNCTION_TEMPLATE_ARGS
0273                           >
0274                        >::type type;
0275       };
0276 
0277       template<
0278         typename FunctionObj,
0279         typename R BOOST_FUNCTION_COMMA
0280         BOOST_FUNCTION_TEMPLATE_PARMS
0281        >
0282       struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
0283       {
0284         typedef typename conditional<(is_void<R>::value),
0285                             BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
0286                             FunctionObj,
0287                             R BOOST_FUNCTION_COMMA
0288                             BOOST_FUNCTION_TEMPLATE_ARGS
0289                           >,
0290                           BOOST_FUNCTION_FUNCTION_REF_INVOKER<
0291                             FunctionObj,
0292                             R BOOST_FUNCTION_COMMA
0293                             BOOST_FUNCTION_TEMPLATE_ARGS
0294                           >
0295                        >::type type;
0296       };
0297 
0298 #if BOOST_FUNCTION_NUM_ARGS > 0
0299       /* Retrieve the appropriate invoker for a member pointer.  */
0300       template<
0301         typename MemberPtr,
0302         typename R BOOST_FUNCTION_COMMA
0303         BOOST_FUNCTION_TEMPLATE_PARMS
0304        >
0305       struct BOOST_FUNCTION_GET_MEMBER_INVOKER
0306       {
0307         typedef typename conditional<(is_void<R>::value),
0308                             BOOST_FUNCTION_VOID_MEMBER_INVOKER<
0309                             MemberPtr,
0310                             R BOOST_FUNCTION_COMMA
0311                             BOOST_FUNCTION_TEMPLATE_ARGS
0312                           >,
0313                           BOOST_FUNCTION_MEMBER_INVOKER<
0314                             MemberPtr,
0315                             R BOOST_FUNCTION_COMMA
0316                             BOOST_FUNCTION_TEMPLATE_ARGS
0317                           >
0318                        >::type type;
0319       };
0320 #endif
0321 
0322       /* Given the tag returned by get_function_tag, retrieve the
0323          actual invoker that will be used for the given function
0324          object.
0325 
0326          Each specialization contains an "apply" nested class template
0327          that accepts the function object, return type, function
0328          argument types, and allocator. The resulting "apply" class
0329          contains two typedefs, "invoker_type" and "manager_type",
0330          which correspond to the invoker and manager types. */
0331       template<typename Tag>
0332       struct BOOST_FUNCTION_GET_INVOKER { };
0333 
0334       /* Retrieve the invoker for a function pointer. */
0335       template<>
0336       struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
0337       {
0338         template<typename FunctionPtr,
0339                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
0340         struct apply
0341         {
0342           typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
0343                              FunctionPtr,
0344                              R BOOST_FUNCTION_COMMA
0345                              BOOST_FUNCTION_TEMPLATE_ARGS
0346                            >::type
0347             invoker_type;
0348 
0349           typedef functor_manager<FunctionPtr> manager_type;
0350         };
0351 
0352         template<typename FunctionPtr, typename Allocator,
0353                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
0354         struct apply_a
0355         {
0356           typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
0357                              FunctionPtr,
0358                              R BOOST_FUNCTION_COMMA
0359                              BOOST_FUNCTION_TEMPLATE_ARGS
0360                            >::type
0361             invoker_type;
0362 
0363           typedef functor_manager<FunctionPtr> manager_type;
0364         };
0365       };
0366 
0367 #if BOOST_FUNCTION_NUM_ARGS > 0
0368       /* Retrieve the invoker for a member pointer. */
0369       template<>
0370       struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
0371       {
0372         template<typename MemberPtr,
0373                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
0374         struct apply
0375         {
0376           typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
0377                              MemberPtr,
0378                              R BOOST_FUNCTION_COMMA
0379                              BOOST_FUNCTION_TEMPLATE_ARGS
0380                            >::type
0381             invoker_type;
0382 
0383           typedef functor_manager<MemberPtr> manager_type;
0384         };
0385 
0386         template<typename MemberPtr, typename Allocator,
0387                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
0388         struct apply_a
0389         {
0390           typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
0391                              MemberPtr,
0392                              R BOOST_FUNCTION_COMMA
0393                              BOOST_FUNCTION_TEMPLATE_ARGS
0394                            >::type
0395             invoker_type;
0396 
0397           typedef functor_manager<MemberPtr> manager_type;
0398         };
0399       };
0400 #endif
0401 
0402       /* Retrieve the invoker for a function object. */
0403       template<>
0404       struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag>
0405       {
0406         template<typename FunctionObj,
0407                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
0408         struct apply
0409         {
0410           typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
0411                              FunctionObj,
0412                              R BOOST_FUNCTION_COMMA
0413                              BOOST_FUNCTION_TEMPLATE_ARGS
0414                            >::type
0415             invoker_type;
0416 
0417           typedef functor_manager<FunctionObj> manager_type;
0418         };
0419 
0420         template<typename FunctionObj, typename Allocator,
0421                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
0422         struct apply_a
0423         {
0424           typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
0425                              FunctionObj,
0426                              R BOOST_FUNCTION_COMMA
0427                              BOOST_FUNCTION_TEMPLATE_ARGS
0428                            >::type
0429             invoker_type;
0430 
0431           typedef functor_manager_a<FunctionObj, Allocator> manager_type;
0432         };
0433       };
0434 
0435       /* Retrieve the invoker for a reference to a function object. */
0436       template<>
0437       struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
0438       {
0439         template<typename RefWrapper,
0440                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
0441         struct apply
0442         {
0443           typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
0444                              typename RefWrapper::type,
0445                              R BOOST_FUNCTION_COMMA
0446                              BOOST_FUNCTION_TEMPLATE_ARGS
0447                            >::type
0448             invoker_type;
0449 
0450           typedef reference_manager<typename RefWrapper::type> manager_type;
0451         };
0452 
0453         template<typename RefWrapper, typename Allocator,
0454                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
0455         struct apply_a
0456         {
0457           typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
0458                              typename RefWrapper::type,
0459                              R BOOST_FUNCTION_COMMA
0460                              BOOST_FUNCTION_TEMPLATE_ARGS
0461                            >::type
0462             invoker_type;
0463 
0464           typedef reference_manager<typename RefWrapper::type> manager_type;
0465         };
0466       };
0467 
0468 
0469       /**
0470        * vtable for a specific boost::function instance. This
0471        * structure must be an aggregate so that we can use static
0472        * initialization in boost::function's assign_to and assign_to_a
0473        * members. It therefore cannot have any constructors,
0474        * destructors, base classes, etc.
0475        */
0476       template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
0477       struct BOOST_FUNCTION_VTABLE
0478       {
0479 #ifndef BOOST_NO_VOID_RETURNS
0480         typedef R         result_type;
0481 #else
0482         typedef typename function_return_type<R>::type result_type;
0483 #endif // BOOST_NO_VOID_RETURNS
0484 
0485         typedef result_type (*invoker_type)(function_buffer&
0486                                             BOOST_FUNCTION_COMMA
0487                                             BOOST_FUNCTION_TEMPLATE_ARGS);
0488 
0489         template<typename F>
0490         bool assign_to(F f, function_buffer& functor) const
0491         {
0492           typedef typename get_function_tag<F>::type tag;
0493           return assign_to(f, functor, tag());
0494         }
0495         template<typename F,typename Allocator>
0496         bool assign_to_a(F f, function_buffer& functor, Allocator a) const
0497         {
0498           typedef typename get_function_tag<F>::type tag;
0499           return assign_to_a(f, functor, a, tag());
0500         }
0501 
0502         void clear(function_buffer& functor) const
0503         {
0504 #if defined(BOOST_GCC) && (__GNUC__ >= 11)
0505 # pragma GCC diagnostic push
0506 // False positive in GCC 11/12 for empty function objects
0507 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
0508 #endif
0509           if (base.manager)
0510             base.manager(functor, functor, destroy_functor_tag);
0511 #if defined(BOOST_GCC) && (__GNUC__ >= 11)
0512 # pragma GCC diagnostic pop
0513 #endif
0514         }
0515 
0516       private:
0517         // Function pointers
0518         template<typename FunctionPtr>
0519         bool
0520         assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const
0521         {
0522           this->clear(functor);
0523           if (f) {
0524             // should be a reinterpret cast, but some compilers insist
0525             // on giving cv-qualifiers to free functions
0526             functor.members.func_ptr = reinterpret_cast<void (*)()>(f);
0527             return true;
0528           } else {
0529             return false;
0530           }
0531         }
0532         template<typename FunctionPtr,typename Allocator>
0533         bool
0534         assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const
0535         {
0536           return assign_to(f,functor,function_ptr_tag());
0537         }
0538 
0539         // Member pointers
0540 #if BOOST_FUNCTION_NUM_ARGS > 0
0541         template<typename MemberPtr>
0542         bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const
0543         {
0544           // DPG TBD: Add explicit support for member function
0545           // objects, so we invoke through mem_fn() but we retain the
0546           // right target_type() values.
0547           if (f) {
0548             this->assign_to(boost::mem_fn(f), functor);
0549             return true;
0550           } else {
0551             return false;
0552           }
0553         }
0554         template<typename MemberPtr,typename Allocator>
0555         bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const
0556         {
0557           // DPG TBD: Add explicit support for member function
0558           // objects, so we invoke through mem_fn() but we retain the
0559           // right target_type() values.
0560           if (f) {
0561             this->assign_to_a(boost::mem_fn(f), functor, a);
0562             return true;
0563           } else {
0564             return false;
0565           }
0566         }
0567 #endif // BOOST_FUNCTION_NUM_ARGS > 0
0568 
0569         // Function objects
0570         // Assign to a function object using the small object optimization
0571         template<typename FunctionObj>
0572         void
0573         assign_functor(FunctionObj f, function_buffer& functor, true_type) const
0574         {
0575           new (reinterpret_cast<void*>(functor.data)) FunctionObj(f);
0576         }
0577         template<typename FunctionObj,typename Allocator>
0578         void
0579         assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, true_type) const
0580         {
0581           assign_functor(f,functor,true_type());
0582         }
0583 
0584         // Assign to a function object allocated on the heap.
0585         template<typename FunctionObj>
0586         void
0587         assign_functor(FunctionObj f, function_buffer& functor, false_type) const
0588         {
0589           functor.members.obj_ptr = new FunctionObj(f);
0590         }
0591         template<typename FunctionObj,typename Allocator>
0592         void
0593         assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, false_type) const
0594         {
0595           typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
0596 #if defined(BOOST_NO_CXX11_ALLOCATOR)
0597           typedef typename Allocator::template rebind<functor_wrapper_type>::other
0598             wrapper_allocator_type;
0599           typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
0600 #else
0601           using wrapper_allocator_type = typename std::allocator_traits<Allocator>::template rebind_alloc<functor_wrapper_type>;
0602           using wrapper_allocator_pointer_type = typename std::allocator_traits<wrapper_allocator_type>::pointer;
0603 #endif
0604           wrapper_allocator_type wrapper_allocator(a);
0605           wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
0606 #if defined(BOOST_NO_CXX11_ALLOCATOR)
0607           wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
0608 #else
0609           std::allocator_traits<wrapper_allocator_type>::construct(wrapper_allocator, copy, functor_wrapper_type(f,a));
0610 #endif
0611           functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
0612           functor.members.obj_ptr = new_f;
0613         }
0614 
0615         template<typename FunctionObj>
0616         bool
0617         assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const
0618         {
0619           if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
0620             assign_functor(f, functor,
0621                            integral_constant<bool, (function_allows_small_object_optimization<FunctionObj>::value)>());
0622             return true;
0623           } else {
0624             return false;
0625           }
0626         }
0627         template<typename FunctionObj,typename Allocator>
0628         bool
0629         assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const
0630         {
0631           if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
0632             assign_functor_a(f, functor, a,
0633                            integral_constant<bool, (function_allows_small_object_optimization<FunctionObj>::value)>());
0634             return true;
0635           } else {
0636             return false;
0637           }
0638         }
0639 
0640         // Reference to a function object
0641         template<typename FunctionObj>
0642         bool
0643         assign_to(const reference_wrapper<FunctionObj>& f,
0644                   function_buffer& functor, function_obj_ref_tag) const
0645         {
0646           functor.members.obj_ref.obj_ptr = (void *)(f.get_pointer());
0647           functor.members.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
0648           functor.members.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
0649           return true;
0650         }
0651         template<typename FunctionObj,typename Allocator>
0652         bool
0653         assign_to_a(const reference_wrapper<FunctionObj>& f,
0654                   function_buffer& functor, Allocator, function_obj_ref_tag) const
0655         {
0656           return assign_to(f,functor,function_obj_ref_tag());
0657         }
0658 
0659       public:
0660         vtable_base base;
0661         invoker_type invoker;
0662       };
0663     } // end namespace function
0664   } // end namespace detail
0665 
0666   template<
0667     typename R BOOST_FUNCTION_COMMA
0668     BOOST_FUNCTION_TEMPLATE_PARMS
0669   >
0670   class BOOST_FUNCTION_FUNCTION : public function_base
0671   {
0672   public:
0673 #ifndef BOOST_NO_VOID_RETURNS
0674     typedef R         result_type;
0675 #else
0676     typedef  typename boost::detail::function::function_return_type<R>::type
0677       result_type;
0678 #endif // BOOST_NO_VOID_RETURNS
0679 
0680   private:
0681     typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
0682               R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
0683       vtable_type;
0684 
0685     vtable_type* get_vtable() const {
0686       return reinterpret_cast<vtable_type*>(
0687                reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
0688     }
0689 
0690     struct clear_type {};
0691 
0692   public:
0693     BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
0694 
0695     // add signature for boost::lambda
0696     template<typename Args>
0697     struct sig
0698     {
0699       typedef result_type type;
0700     };
0701 
0702 #if BOOST_FUNCTION_NUM_ARGS == 1
0703     typedef T0 argument_type;
0704 #elif BOOST_FUNCTION_NUM_ARGS == 2
0705     typedef T0 first_argument_type;
0706     typedef T1 second_argument_type;
0707 #endif
0708 
0709     BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
0710     BOOST_FUNCTION_ARG_TYPES
0711 
0712     typedef BOOST_FUNCTION_FUNCTION self_type;
0713 
0714     BOOST_DEFAULTED_FUNCTION(BOOST_FUNCTION_FUNCTION(), : function_base() {})
0715 
0716     // MSVC chokes if the following two constructors are collapsed into
0717     // one with a default parameter.
0718     template<typename Functor>
0719     BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
0720 #ifndef BOOST_NO_SFINAE
0721                             ,typename boost::enable_if_<
0722                              !(is_integral<Functor>::value),
0723                                         int>::type = 0
0724 #endif // BOOST_NO_SFINAE
0725                             ) :
0726       function_base()
0727     {
0728       this->assign_to(f);
0729     }
0730     template<typename Functor,typename Allocator>
0731     BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
0732 #ifndef BOOST_NO_SFINAE
0733                             ,typename boost::enable_if_<
0734                               !(is_integral<Functor>::value),
0735                                         int>::type = 0
0736 #endif // BOOST_NO_SFINAE
0737                             ) :
0738       function_base()
0739     {
0740       this->assign_to_a(f,a);
0741     }
0742 
0743 #ifndef BOOST_NO_SFINAE
0744     BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
0745 #else
0746     BOOST_FUNCTION_FUNCTION(int zero) : function_base()
0747     {
0748       BOOST_ASSERT(zero == 0);
0749     }
0750 #endif
0751 
0752     BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
0753     {
0754       this->assign_to_own(f);
0755     }
0756 
0757 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0758     BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base()
0759     {
0760       this->move_assign(f);
0761     }
0762 #endif
0763 
0764     ~BOOST_FUNCTION_FUNCTION() { clear(); }
0765 
0766     result_type operator()(BOOST_FUNCTION_PARMS) const
0767     {
0768       if (this->empty())
0769         boost::throw_exception(bad_function_call());
0770 
0771       return get_vtable()->invoker
0772                (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
0773     }
0774 
0775     // The distinction between when to use BOOST_FUNCTION_FUNCTION and
0776     // when to use self_type is obnoxious. MSVC cannot handle self_type as
0777     // the return type of these assignment operators, but Borland C++ cannot
0778     // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
0779     // construct.
0780     template<typename Functor>
0781 #ifndef BOOST_NO_SFINAE
0782     typename boost::enable_if_<
0783                   !(is_integral<Functor>::value),
0784                BOOST_FUNCTION_FUNCTION&>::type
0785 #else
0786     BOOST_FUNCTION_FUNCTION&
0787 #endif
0788     operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
0789     {
0790       this->clear();
0791       BOOST_TRY  {
0792         this->assign_to(f);
0793       } BOOST_CATCH (...) {
0794         vtable = 0;
0795         BOOST_RETHROW;
0796       }
0797       BOOST_CATCH_END
0798       return *this;
0799     }
0800     template<typename Functor,typename Allocator>
0801     void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
0802     {
0803       this->clear();
0804       BOOST_TRY{
0805         this->assign_to_a(f,a);
0806       } BOOST_CATCH (...) {
0807         vtable = 0;
0808         BOOST_RETHROW;
0809       }
0810       BOOST_CATCH_END
0811     }
0812 
0813 #ifndef BOOST_NO_SFINAE
0814     BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
0815     {
0816       this->clear();
0817       return *this;
0818     }
0819 #else
0820     BOOST_FUNCTION_FUNCTION& operator=(int zero)
0821     {
0822       BOOST_ASSERT(zero == 0);
0823       this->clear();
0824       return *this;
0825     }
0826 #endif
0827 
0828     // Assignment from another BOOST_FUNCTION_FUNCTION
0829     BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
0830     {
0831       if (&f == this)
0832         return *this;
0833 
0834       this->clear();
0835       BOOST_TRY {
0836         this->assign_to_own(f);
0837       } BOOST_CATCH (...) {
0838         vtable = 0;
0839         BOOST_RETHROW;
0840       }
0841       BOOST_CATCH_END
0842       return *this;
0843     }
0844 
0845 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0846     // Move assignment from another BOOST_FUNCTION_FUNCTION
0847     BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f)
0848     {
0849       if (&f == this)
0850         return *this;
0851 
0852       this->clear();
0853       BOOST_TRY {
0854         this->move_assign(f);
0855       } BOOST_CATCH (...) {
0856         vtable = 0;
0857         BOOST_RETHROW;
0858       }
0859       BOOST_CATCH_END
0860       return *this;
0861     }
0862 #endif
0863 
0864     void swap(BOOST_FUNCTION_FUNCTION& other)
0865     {
0866       if (&other == this)
0867         return;
0868 
0869       BOOST_FUNCTION_FUNCTION tmp;
0870       tmp.move_assign(*this);
0871       this->move_assign(other);
0872       other.move_assign(tmp);
0873     }
0874 
0875     // Clear out a target, if there is one
0876     void clear()
0877     {
0878       if (vtable) {
0879         if (!this->has_trivial_copy_and_destroy())
0880           get_vtable()->clear(this->functor);
0881         vtable = 0;
0882       }
0883     }
0884 
0885 #if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
0886     // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
0887     operator bool () const { return !this->empty(); }
0888 #else
0889   private:
0890     struct dummy {
0891       void nonnull() {}
0892     };
0893 
0894     typedef void (dummy::*safe_bool)();
0895 
0896   public:
0897     operator safe_bool () const
0898       { return (this->empty())? 0 : &dummy::nonnull; }
0899 
0900     bool operator!() const
0901       { return this->empty(); }
0902 #endif
0903 
0904   private:
0905     void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
0906     {
0907       if (!f.empty()) {
0908         this->vtable = f.vtable;
0909         if (this->has_trivial_copy_and_destroy()) {
0910           // Don't operate on storage directly since union type doesn't relax
0911           // strict aliasing rules, despite of having member char type.
0912 #         if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
0913 #           pragma GCC diagnostic push
0914             // This warning is technically correct, but we don't want to pay the price for initializing
0915             // just to silence a warning: https://github.com/boostorg/function/issues/27
0916 #           pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
0917 #           if (BOOST_GCC >= 110000)
0918               // GCC 11.3, 12 emit a different warning: https://github.com/boostorg/function/issues/42
0919 #             pragma GCC diagnostic ignored "-Wuninitialized"
0920 #           endif
0921 #         endif
0922           std::memcpy(this->functor.data, f.functor.data, sizeof(boost::detail::function::function_buffer));
0923 #         if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
0924 #           pragma GCC diagnostic pop
0925 #         endif
0926         } else
0927           get_vtable()->base.manager(f.functor, this->functor,
0928                                      boost::detail::function::clone_functor_tag);
0929       }
0930     }
0931 
0932     template<typename Functor>
0933     void assign_to(Functor f)
0934     {
0935       using boost::detail::function::vtable_base;
0936 
0937       typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
0938       typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
0939       typedef typename get_invoker::
0940                          template apply<Functor, R BOOST_FUNCTION_COMMA
0941                         BOOST_FUNCTION_TEMPLATE_ARGS>
0942         handler_type;
0943 
0944       typedef typename handler_type::invoker_type invoker_type;
0945       typedef typename handler_type::manager_type manager_type;
0946 
0947       // Note: it is extremely important that this initialization use
0948       // static initialization. Otherwise, we will have a race
0949       // condition here in multi-threaded code. See
0950       // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
0951       static const vtable_type stored_vtable =
0952         { { &manager_type::manage }, &invoker_type::invoke };
0953 
0954       if (stored_vtable.assign_to(f, functor)) {
0955         std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
0956         // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
0957         if (boost::has_trivial_copy_constructor<Functor>::value &&
0958             boost::has_trivial_destructor<Functor>::value &&
0959             boost::detail::function::function_allows_small_object_optimization<Functor>::value)
0960           value |= static_cast<std::size_t>(0x01);
0961         vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
0962       } else
0963         vtable = 0;
0964     }
0965 
0966     template<typename Functor,typename Allocator>
0967     void assign_to_a(Functor f,Allocator a)
0968     {
0969       using boost::detail::function::vtable_base;
0970 
0971       typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
0972       typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
0973       typedef typename get_invoker::
0974                          template apply_a<Functor, Allocator, R BOOST_FUNCTION_COMMA
0975                          BOOST_FUNCTION_TEMPLATE_ARGS>
0976         handler_type;
0977 
0978       typedef typename handler_type::invoker_type invoker_type;
0979       typedef typename handler_type::manager_type manager_type;
0980 
0981       // Note: it is extremely important that this initialization use
0982       // static initialization. Otherwise, we will have a race
0983       // condition here in multi-threaded code. See
0984       // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
0985       static const vtable_type stored_vtable =
0986         { { &manager_type::manage }, &invoker_type::invoke };
0987 
0988       if (stored_vtable.assign_to_a(f, functor, a)) {
0989         std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
0990         // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
0991         if (boost::has_trivial_copy_constructor<Functor>::value &&
0992             boost::has_trivial_destructor<Functor>::value &&
0993             boost::detail::function::function_allows_small_object_optimization<Functor>::value)
0994           value |= static_cast<std::size_t>(0x01);
0995         vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
0996       } else
0997         vtable = 0;
0998     }
0999 
1000     // Moves the value from the specified argument to *this. If the argument
1001     // has its function object allocated on the heap, move_assign will pass
1002     // its buffer to *this, and set the argument's buffer pointer to NULL.
1003     void move_assign(BOOST_FUNCTION_FUNCTION& f)
1004     {
1005       if (&f == this)
1006         return;
1007 
1008       BOOST_TRY {
1009         if (!f.empty()) {
1010           this->vtable = f.vtable;
1011           if (this->has_trivial_copy_and_destroy()) {
1012             // Don't operate on storage directly since union type doesn't relax
1013             // strict aliasing rules, despite of having member char type.
1014 #           if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
1015 #             pragma GCC diagnostic push
1016               // This warning is technically correct, but we don't want to pay the price for initializing
1017               // just to silence a warning: https://github.com/boostorg/function/issues/27
1018 #             pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1019 #             if (BOOST_GCC >= 120000)
1020                 // GCC 12 emits a different warning: https://github.com/boostorg/function/issues/42
1021 #               pragma GCC diagnostic ignored "-Wuninitialized"
1022 #             endif
1023 #           endif
1024             std::memcpy(this->functor.data, f.functor.data, sizeof(this->functor.data));
1025 #           if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
1026 #             pragma GCC diagnostic pop
1027 #           endif
1028           } else
1029 #if defined(BOOST_GCC) && (__GNUC__ >= 11)
1030 # pragma GCC diagnostic push
1031 // False positive in GCC 11/12 for empty function objects (function_n_test.cpp:673)
1032 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1033 #endif
1034             get_vtable()->base.manager(f.functor, this->functor,
1035                                      boost::detail::function::move_functor_tag);
1036 #if defined(BOOST_GCC) && (__GNUC__ >= 11)
1037 # pragma GCC diagnostic pop
1038 #endif
1039           f.vtable = 0;
1040         } else {
1041           clear();
1042         }
1043       } BOOST_CATCH (...) {
1044         vtable = 0;
1045         BOOST_RETHROW;
1046       }
1047       BOOST_CATCH_END
1048     }
1049   };
1050 
1051   template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1052   inline void swap(BOOST_FUNCTION_FUNCTION<
1053                      R BOOST_FUNCTION_COMMA
1054                      BOOST_FUNCTION_TEMPLATE_ARGS
1055                    >& f1,
1056                    BOOST_FUNCTION_FUNCTION<
1057                      R BOOST_FUNCTION_COMMA
1058                      BOOST_FUNCTION_TEMPLATE_ARGS
1059                    >& f2)
1060   {
1061     f1.swap(f2);
1062   }
1063 
1064 // Poison comparisons between boost::function objects of the same type.
1065 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1066   void operator==(const BOOST_FUNCTION_FUNCTION<
1067                           R BOOST_FUNCTION_COMMA
1068                           BOOST_FUNCTION_TEMPLATE_ARGS>&,
1069                   const BOOST_FUNCTION_FUNCTION<
1070                           R BOOST_FUNCTION_COMMA
1071                           BOOST_FUNCTION_TEMPLATE_ARGS>&);
1072 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
1073   void operator!=(const BOOST_FUNCTION_FUNCTION<
1074                           R BOOST_FUNCTION_COMMA
1075                           BOOST_FUNCTION_TEMPLATE_ARGS>&,
1076                   const BOOST_FUNCTION_FUNCTION<
1077                           R BOOST_FUNCTION_COMMA
1078                           BOOST_FUNCTION_TEMPLATE_ARGS>& );
1079 
1080 #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
1081 
1082 #if BOOST_FUNCTION_NUM_ARGS == 0
1083 #define BOOST_FUNCTION_PARTIAL_SPEC R (void)
1084 #else
1085 #define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_FUNCTION_TEMPLATE_ARGS)
1086 #endif
1087 
1088 template<typename R BOOST_FUNCTION_COMMA
1089          BOOST_FUNCTION_TEMPLATE_PARMS>
1090 class function<BOOST_FUNCTION_PARTIAL_SPEC>
1091   : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
1092 {
1093   typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
1094   typedef function self_type;
1095 
1096   struct clear_type {};
1097 
1098 public:
1099 
1100   BOOST_DEFAULTED_FUNCTION(function(), : base_type() {})
1101 
1102   template<typename Functor>
1103   function(Functor f
1104 #ifndef BOOST_NO_SFINAE
1105            ,typename boost::enable_if_<
1106                           !(is_integral<Functor>::value),
1107                        int>::type = 0
1108 #endif
1109            ) :
1110     base_type(f)
1111   {
1112   }
1113   template<typename Functor,typename Allocator>
1114   function(Functor f, Allocator a
1115 #ifndef BOOST_NO_SFINAE
1116            ,typename boost::enable_if_<
1117                            !(is_integral<Functor>::value),
1118                        int>::type = 0
1119 #endif
1120            ) :
1121     base_type(f,a)
1122   {
1123   }
1124 
1125 #ifndef BOOST_NO_SFINAE
1126   function(clear_type*) : base_type() {}
1127 #endif
1128 
1129   function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
1130 
1131   function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
1132 
1133 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1134   // Move constructors
1135   function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
1136   function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
1137 #endif
1138 
1139   self_type& operator=(const self_type& f)
1140   {
1141     self_type(f).swap(*this);
1142     return *this;
1143   }
1144 
1145 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1146   self_type& operator=(self_type&& f)
1147   {
1148     self_type(static_cast<self_type&&>(f)).swap(*this);
1149     return *this;
1150   }
1151 #endif
1152 
1153   template<typename Functor>
1154 #ifndef BOOST_NO_SFINAE
1155   typename boost::enable_if_<
1156                          !(is_integral<Functor>::value),
1157                       self_type&>::type
1158 #else
1159   self_type&
1160 #endif
1161   operator=(Functor f)
1162   {
1163     self_type(f).swap(*this);
1164     return *this;
1165   }
1166 
1167 #ifndef BOOST_NO_SFINAE
1168   self_type& operator=(clear_type*)
1169   {
1170     this->clear();
1171     return *this;
1172   }
1173 #endif
1174 
1175   self_type& operator=(const base_type& f)
1176   {
1177     self_type(f).swap(*this);
1178     return *this;
1179   }
1180 
1181 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1182   self_type& operator=(base_type&& f)
1183   {
1184     self_type(static_cast<base_type&&>(f)).swap(*this);
1185     return *this;
1186   }
1187 #endif
1188 };
1189 
1190 #undef BOOST_FUNCTION_PARTIAL_SPEC
1191 #endif // have partial specialization
1192 
1193 } // end namespace boost
1194 
1195 // Cleanup after ourselves...
1196 #undef BOOST_FUNCTION_VTABLE
1197 #undef BOOST_FUNCTION_COMMA
1198 #undef BOOST_FUNCTION_FUNCTION
1199 #undef BOOST_FUNCTION_FUNCTION_INVOKER
1200 #undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
1201 #undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
1202 #undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
1203 #undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
1204 #undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
1205 #undef BOOST_FUNCTION_MEMBER_INVOKER
1206 #undef BOOST_FUNCTION_VOID_MEMBER_INVOKER
1207 #undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
1208 #undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
1209 #undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
1210 #undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
1211 #undef BOOST_FUNCTION_GET_INVOKER
1212 #undef BOOST_FUNCTION_TEMPLATE_PARMS
1213 #undef BOOST_FUNCTION_TEMPLATE_ARGS
1214 #undef BOOST_FUNCTION_PARMS
1215 #undef BOOST_FUNCTION_PARM
1216 #ifdef BOOST_FUNCTION_ARG
1217 #   undef BOOST_FUNCTION_ARG
1218 #endif
1219 #undef BOOST_FUNCTION_ARGS
1220 #undef BOOST_FUNCTION_ARG_TYPE
1221 #undef BOOST_FUNCTION_ARG_TYPES
1222 #undef BOOST_FUNCTION_VOID_RETURN_TYPE
1223 #undef BOOST_FUNCTION_RETURN
1224 
1225 #if defined(BOOST_MSVC)
1226 #   pragma warning( pop )
1227 #endif