imgtools/imglib/boostlibrary/boost/function/function_template.hpp
changeset 0 044383f39525
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 // Boost.Function library
       
     2 
       
     3 //  Copyright Douglas Gregor 2001-2006
       
     4 //  Copyright Emil Dotchevski 2007
       
     5 //  Use, modification and distribution is subject to the Boost Software License, Version 1.0.
       
     6 //  (See accompanying file LICENSE_1_0.txt or copy at
       
     7 //  http://www.boost.org/LICENSE_1_0.txt)
       
     8 
       
     9 // For more information, see http://www.boost.org
       
    10 
       
    11 // Note: this header is a header template and must NOT have multiple-inclusion
       
    12 // protection.
       
    13 #include <boost/function/detail/prologue.hpp>
       
    14 
       
    15 #if defined(BOOST_MSVC)
       
    16 #   pragma warning( push )
       
    17 #   pragma warning( disable : 4127 ) // "conditional expression is constant"
       
    18 #endif       
       
    19 
       
    20 #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
       
    21 
       
    22 #define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
       
    23 
       
    24 #define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
       
    25 
       
    26 #define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
       
    27 
       
    28 #define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
       
    29 
       
    30 #define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
       
    31   typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
       
    32 
       
    33 #define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
       
    34 
       
    35 // Comma if nonzero number of arguments
       
    36 #if BOOST_FUNCTION_NUM_ARGS == 0
       
    37 #  define BOOST_FUNCTION_COMMA
       
    38 #else
       
    39 #  define BOOST_FUNCTION_COMMA ,
       
    40 #endif // BOOST_FUNCTION_NUM_ARGS > 0
       
    41 
       
    42 // Class names used in this version of the code
       
    43 #define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
       
    44 #define BOOST_FUNCTION_FUNCTION_INVOKER \
       
    45   BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    46 #define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
       
    47   BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    48 #define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
       
    49   BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    50 #define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
       
    51   BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    52 #define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
       
    53   BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    54 #define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
       
    55   BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    56 #define BOOST_FUNCTION_MEMBER_INVOKER \
       
    57   BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    58 #define BOOST_FUNCTION_VOID_MEMBER_INVOKER \
       
    59   BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    60 #define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
       
    61   BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    62 #define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
       
    63   BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    64 #define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
       
    65   BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    66 #define BOOST_FUNCTION_GET_MEMBER_INVOKER \
       
    67   BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    68 #define BOOST_FUNCTION_GET_INVOKER \
       
    69   BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS)
       
    70 #define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
       
    71 
       
    72 #ifndef BOOST_NO_VOID_RETURNS
       
    73 #  define BOOST_FUNCTION_VOID_RETURN_TYPE void
       
    74 #  define BOOST_FUNCTION_RETURN(X) X
       
    75 #else
       
    76 #  define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
       
    77 #  define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
       
    78 #endif
       
    79 
       
    80 namespace boost {
       
    81   namespace detail {
       
    82     namespace function {
       
    83       template<
       
    84         typename FunctionPtr,
       
    85         typename R BOOST_FUNCTION_COMMA
       
    86         BOOST_FUNCTION_TEMPLATE_PARMS
       
    87         >
       
    88       struct BOOST_FUNCTION_FUNCTION_INVOKER
       
    89       {
       
    90         static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
       
    91                         BOOST_FUNCTION_PARMS)
       
    92         {
       
    93           FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
       
    94           return f(BOOST_FUNCTION_ARGS);
       
    95         }
       
    96       };
       
    97 
       
    98       template<
       
    99         typename FunctionPtr,
       
   100         typename R BOOST_FUNCTION_COMMA
       
   101         BOOST_FUNCTION_TEMPLATE_PARMS
       
   102         >
       
   103       struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
       
   104       {
       
   105         static BOOST_FUNCTION_VOID_RETURN_TYPE
       
   106         invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
       
   107                BOOST_FUNCTION_PARMS)
       
   108 
       
   109         {
       
   110           FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
       
   111           BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
       
   112         }
       
   113       };
       
   114 
       
   115       template<
       
   116         typename FunctionObj,
       
   117         typename R BOOST_FUNCTION_COMMA
       
   118         BOOST_FUNCTION_TEMPLATE_PARMS
       
   119       >
       
   120       struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
       
   121       {
       
   122         static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
       
   123                         BOOST_FUNCTION_PARMS)
       
   124 
       
   125         {
       
   126           FunctionObj* f;
       
   127           if (function_allows_small_object_optimization<FunctionObj>::value)
       
   128             f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
       
   129           else
       
   130             f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
       
   131           return (*f)(BOOST_FUNCTION_ARGS);
       
   132         }
       
   133       };
       
   134 
       
   135       template<
       
   136         typename FunctionObj,
       
   137         typename R BOOST_FUNCTION_COMMA
       
   138         BOOST_FUNCTION_TEMPLATE_PARMS
       
   139       >
       
   140       struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
       
   141       {
       
   142         static BOOST_FUNCTION_VOID_RETURN_TYPE
       
   143         invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
       
   144                BOOST_FUNCTION_PARMS)
       
   145 
       
   146         {
       
   147           FunctionObj* f;
       
   148           if (function_allows_small_object_optimization<FunctionObj>::value)
       
   149             f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
       
   150           else
       
   151             f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
       
   152           BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
       
   153         }
       
   154       };
       
   155 
       
   156       template<
       
   157         typename FunctionObj,
       
   158         typename R BOOST_FUNCTION_COMMA
       
   159         BOOST_FUNCTION_TEMPLATE_PARMS
       
   160       >
       
   161       struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
       
   162       {
       
   163         static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
       
   164                         BOOST_FUNCTION_PARMS)
       
   165 
       
   166         {
       
   167           FunctionObj* f = 
       
   168             reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
       
   169           return (*f)(BOOST_FUNCTION_ARGS);
       
   170         }
       
   171       };
       
   172 
       
   173       template<
       
   174         typename FunctionObj,
       
   175         typename R BOOST_FUNCTION_COMMA
       
   176         BOOST_FUNCTION_TEMPLATE_PARMS
       
   177       >
       
   178       struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
       
   179       {
       
   180         static BOOST_FUNCTION_VOID_RETURN_TYPE
       
   181         invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
       
   182                BOOST_FUNCTION_PARMS)
       
   183 
       
   184         {
       
   185           FunctionObj* f = 
       
   186             reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
       
   187           BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
       
   188         }
       
   189       };
       
   190 
       
   191 #if BOOST_FUNCTION_NUM_ARGS > 0
       
   192       /* Handle invocation of member pointers. */
       
   193       template<
       
   194         typename MemberPtr,
       
   195         typename R BOOST_FUNCTION_COMMA
       
   196         BOOST_FUNCTION_TEMPLATE_PARMS
       
   197       >
       
   198       struct BOOST_FUNCTION_MEMBER_INVOKER
       
   199       {
       
   200         static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
       
   201                         BOOST_FUNCTION_PARMS)
       
   202 
       
   203         {
       
   204           MemberPtr* f = 
       
   205             reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
       
   206           return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
       
   207         }
       
   208       };
       
   209 
       
   210       template<
       
   211         typename MemberPtr,
       
   212         typename R BOOST_FUNCTION_COMMA
       
   213         BOOST_FUNCTION_TEMPLATE_PARMS
       
   214       >
       
   215       struct BOOST_FUNCTION_VOID_MEMBER_INVOKER
       
   216       {
       
   217         static BOOST_FUNCTION_VOID_RETURN_TYPE
       
   218         invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
       
   219                BOOST_FUNCTION_PARMS)
       
   220 
       
   221         {
       
   222           MemberPtr* f = 
       
   223             reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
       
   224           BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
       
   225         }
       
   226       };
       
   227 #endif
       
   228 
       
   229       template<
       
   230         typename FunctionPtr,
       
   231         typename R BOOST_FUNCTION_COMMA
       
   232         BOOST_FUNCTION_TEMPLATE_PARMS
       
   233       >
       
   234       struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
       
   235       {
       
   236         typedef typename mpl::if_c<(is_void<R>::value),
       
   237                             BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
       
   238                             FunctionPtr,
       
   239                             R BOOST_FUNCTION_COMMA
       
   240                             BOOST_FUNCTION_TEMPLATE_ARGS
       
   241                           >,
       
   242                           BOOST_FUNCTION_FUNCTION_INVOKER<
       
   243                             FunctionPtr,
       
   244                             R BOOST_FUNCTION_COMMA
       
   245                             BOOST_FUNCTION_TEMPLATE_ARGS
       
   246                           >
       
   247                        >::type type;
       
   248       };
       
   249 
       
   250       template<
       
   251         typename FunctionObj,
       
   252         typename R BOOST_FUNCTION_COMMA
       
   253         BOOST_FUNCTION_TEMPLATE_PARMS
       
   254        >
       
   255       struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
       
   256       {
       
   257         typedef typename mpl::if_c<(is_void<R>::value),
       
   258                             BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
       
   259                             FunctionObj,
       
   260                             R BOOST_FUNCTION_COMMA
       
   261                             BOOST_FUNCTION_TEMPLATE_ARGS
       
   262                           >,
       
   263                           BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
       
   264                             FunctionObj,
       
   265                             R BOOST_FUNCTION_COMMA
       
   266                             BOOST_FUNCTION_TEMPLATE_ARGS
       
   267                           >
       
   268                        >::type type;
       
   269       };
       
   270 
       
   271       template<
       
   272         typename FunctionObj,
       
   273         typename R BOOST_FUNCTION_COMMA
       
   274         BOOST_FUNCTION_TEMPLATE_PARMS
       
   275        >
       
   276       struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
       
   277       {
       
   278         typedef typename mpl::if_c<(is_void<R>::value),
       
   279                             BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
       
   280                             FunctionObj,
       
   281                             R BOOST_FUNCTION_COMMA
       
   282                             BOOST_FUNCTION_TEMPLATE_ARGS
       
   283                           >,
       
   284                           BOOST_FUNCTION_FUNCTION_REF_INVOKER<
       
   285                             FunctionObj,
       
   286                             R BOOST_FUNCTION_COMMA
       
   287                             BOOST_FUNCTION_TEMPLATE_ARGS
       
   288                           >
       
   289                        >::type type;
       
   290       };
       
   291 
       
   292 #if BOOST_FUNCTION_NUM_ARGS > 0
       
   293       /* Retrieve the appropriate invoker for a member pointer.  */
       
   294       template<
       
   295         typename MemberPtr,
       
   296         typename R BOOST_FUNCTION_COMMA
       
   297         BOOST_FUNCTION_TEMPLATE_PARMS
       
   298        >
       
   299       struct BOOST_FUNCTION_GET_MEMBER_INVOKER
       
   300       {
       
   301         typedef typename mpl::if_c<(is_void<R>::value),
       
   302                             BOOST_FUNCTION_VOID_MEMBER_INVOKER<
       
   303                             MemberPtr,
       
   304                             R BOOST_FUNCTION_COMMA
       
   305                             BOOST_FUNCTION_TEMPLATE_ARGS
       
   306                           >,
       
   307                           BOOST_FUNCTION_MEMBER_INVOKER<
       
   308                             MemberPtr,
       
   309                             R BOOST_FUNCTION_COMMA
       
   310                             BOOST_FUNCTION_TEMPLATE_ARGS
       
   311                           >
       
   312                        >::type type;
       
   313       };
       
   314 #endif
       
   315 
       
   316       /* Given the tag returned by get_function_tag, retrieve the
       
   317          actual invoker that will be used for the given function
       
   318          object. 
       
   319 
       
   320          Each specialization contains an "apply" nested class template
       
   321          that accepts the function object, return type, function
       
   322          argument types, and allocator. The resulting "apply" class
       
   323          contains two typedefs, "invoker_type" and "manager_type",
       
   324          which correspond to the invoker and manager types. */
       
   325       template<typename Tag>
       
   326       struct BOOST_FUNCTION_GET_INVOKER { };
       
   327 
       
   328       /* Retrieve the invoker for a function pointer. */
       
   329       template<>
       
   330       struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
       
   331       {
       
   332         template<typename FunctionPtr,
       
   333                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
       
   334         struct apply
       
   335         {
       
   336           typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
       
   337                              FunctionPtr,
       
   338                              R BOOST_FUNCTION_COMMA
       
   339                              BOOST_FUNCTION_TEMPLATE_ARGS
       
   340                            >::type
       
   341             invoker_type;
       
   342 
       
   343           typedef functor_manager<FunctionPtr> manager_type;
       
   344         };
       
   345 
       
   346         template<typename FunctionPtr,
       
   347                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
       
   348                  typename Allocator>
       
   349         struct apply_a
       
   350         {
       
   351           typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
       
   352                              FunctionPtr,
       
   353                              R BOOST_FUNCTION_COMMA
       
   354                              BOOST_FUNCTION_TEMPLATE_ARGS
       
   355                            >::type
       
   356             invoker_type;
       
   357 
       
   358           typedef functor_manager<FunctionPtr> manager_type;
       
   359         };
       
   360       };
       
   361 
       
   362 #if BOOST_FUNCTION_NUM_ARGS > 0
       
   363       /* Retrieve the invoker for a member pointer. */
       
   364       template<>
       
   365       struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
       
   366       {
       
   367         template<typename MemberPtr,
       
   368                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
       
   369         struct apply
       
   370         {
       
   371           typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
       
   372                              MemberPtr,
       
   373                              R BOOST_FUNCTION_COMMA
       
   374                              BOOST_FUNCTION_TEMPLATE_ARGS
       
   375                            >::type
       
   376             invoker_type;
       
   377 
       
   378           typedef functor_manager<MemberPtr> manager_type;
       
   379         };
       
   380 
       
   381         template<typename MemberPtr,
       
   382                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
       
   383                  typename Allocator>
       
   384         struct apply_a
       
   385         {
       
   386           typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
       
   387                              MemberPtr,
       
   388                              R BOOST_FUNCTION_COMMA
       
   389                              BOOST_FUNCTION_TEMPLATE_ARGS
       
   390                            >::type
       
   391             invoker_type;
       
   392 
       
   393           typedef functor_manager<MemberPtr> manager_type;
       
   394         };
       
   395       };
       
   396 #endif
       
   397 
       
   398       /* Retrieve the invoker for a function object. */
       
   399       template<>
       
   400       struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag>
       
   401       {
       
   402         template<typename FunctionObj,
       
   403                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
       
   404         struct apply
       
   405         {
       
   406           typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
       
   407                              FunctionObj,
       
   408                              R BOOST_FUNCTION_COMMA
       
   409                              BOOST_FUNCTION_TEMPLATE_ARGS
       
   410                            >::type
       
   411             invoker_type;
       
   412 
       
   413           typedef functor_manager<FunctionObj> manager_type;
       
   414         };
       
   415 
       
   416         template<typename FunctionObj,
       
   417                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
       
   418                  typename Allocator>
       
   419         struct apply_a
       
   420         {
       
   421           typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
       
   422                              FunctionObj,
       
   423                              R BOOST_FUNCTION_COMMA
       
   424                              BOOST_FUNCTION_TEMPLATE_ARGS
       
   425                            >::type
       
   426             invoker_type;
       
   427 
       
   428           typedef functor_manager_a<FunctionObj, Allocator> manager_type;
       
   429         };
       
   430       };
       
   431 
       
   432       /* Retrieve the invoker for a reference to a function object. */
       
   433       template<>
       
   434       struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
       
   435       {
       
   436         template<typename RefWrapper,
       
   437                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
       
   438         struct apply
       
   439         {
       
   440           typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
       
   441                              typename RefWrapper::type,
       
   442                              R BOOST_FUNCTION_COMMA
       
   443                              BOOST_FUNCTION_TEMPLATE_ARGS
       
   444                            >::type
       
   445             invoker_type;
       
   446 
       
   447           typedef reference_manager<typename RefWrapper::type> manager_type;
       
   448         };
       
   449 
       
   450         template<typename RefWrapper,
       
   451                  typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
       
   452                  typename Allocator>
       
   453         struct apply_a
       
   454         {
       
   455           typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
       
   456                              typename RefWrapper::type,
       
   457                              R BOOST_FUNCTION_COMMA
       
   458                              BOOST_FUNCTION_TEMPLATE_ARGS
       
   459                            >::type
       
   460             invoker_type;
       
   461 
       
   462           typedef reference_manager<typename RefWrapper::type> manager_type;
       
   463         };
       
   464       };
       
   465 
       
   466 
       
   467       /**
       
   468        * vtable for a specific boost::function instance. This
       
   469        * structure must be an aggregate so that we can use static
       
   470        * initialization in boost::function's assign_to and assign_to_a
       
   471        * members. It therefore cannot have any constructors,
       
   472        * destructors, base classes, etc.
       
   473        */
       
   474       template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
       
   475       struct BOOST_FUNCTION_VTABLE
       
   476       {
       
   477 #ifndef BOOST_NO_VOID_RETURNS
       
   478         typedef R         result_type;
       
   479 #else
       
   480         typedef typename function_return_type<R>::type result_type;
       
   481 #endif // BOOST_NO_VOID_RETURNS
       
   482 
       
   483         typedef result_type (*invoker_type)(function_buffer&
       
   484                                             BOOST_FUNCTION_COMMA
       
   485                                             BOOST_FUNCTION_TEMPLATE_ARGS);
       
   486 
       
   487         template<typename F>
       
   488         bool assign_to(F f, function_buffer& functor)
       
   489         {
       
   490           typedef typename get_function_tag<F>::type tag;
       
   491           return assign_to(f, functor, tag());
       
   492         }
       
   493         template<typename F,typename Allocator>
       
   494         bool assign_to_a(F f, function_buffer& functor, Allocator a)
       
   495         {
       
   496           typedef typename get_function_tag<F>::type tag;
       
   497           return assign_to_a(f, functor, a, tag());
       
   498         }
       
   499 
       
   500         void clear(function_buffer& functor)
       
   501         {
       
   502           if (base.manager)
       
   503             base.manager(functor, functor, destroy_functor_tag);
       
   504         }
       
   505 
       
   506       private:
       
   507         // Function pointers
       
   508         template<typename FunctionPtr>
       
   509         bool 
       
   510         assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag)
       
   511         {
       
   512           this->clear(functor);
       
   513           if (f) {
       
   514             // should be a reinterpret cast, but some compilers insist
       
   515             // on giving cv-qualifiers to free functions
       
   516             functor.func_ptr = (void (*)())(f);
       
   517             return true;
       
   518           } else {
       
   519             return false;
       
   520           }
       
   521         }
       
   522         template<typename FunctionPtr,typename Allocator>
       
   523         bool 
       
   524         assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag)
       
   525         {
       
   526           return assign_to(f,functor,function_ptr_tag());
       
   527         }
       
   528 
       
   529         // Member pointers
       
   530 #if BOOST_FUNCTION_NUM_ARGS > 0
       
   531         template<typename MemberPtr>
       
   532         bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag)
       
   533         {
       
   534           // DPG TBD: Add explicit support for member function
       
   535           // objects, so we invoke through mem_fn() but we retain the
       
   536           // right target_type() values.
       
   537           if (f) {
       
   538             this->assign_to(mem_fn(f), functor);
       
   539             return true;
       
   540           } else {
       
   541             return false;
       
   542           }
       
   543         }
       
   544         template<typename MemberPtr,typename Allocator>
       
   545         bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag)
       
   546         {
       
   547           // DPG TBD: Add explicit support for member function
       
   548           // objects, so we invoke through mem_fn() but we retain the
       
   549           // right target_type() values.
       
   550           if (f) {
       
   551             this->assign_to_a(mem_fn(f), functor, a);
       
   552             return true;
       
   553           } else {
       
   554             return false;
       
   555           }
       
   556         }
       
   557 #endif // BOOST_FUNCTION_NUM_ARGS > 0
       
   558 
       
   559         // Function objects
       
   560         // Assign to a function object using the small object optimization
       
   561         template<typename FunctionObj>
       
   562         void 
       
   563         assign_functor(FunctionObj f, function_buffer& functor, mpl::true_)
       
   564         {
       
   565           new ((void*)&functor.data) FunctionObj(f);
       
   566         }
       
   567         template<typename FunctionObj,typename Allocator>
       
   568         void 
       
   569         assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_)
       
   570         {
       
   571           assign_functor(f,functor,mpl::true_());
       
   572         }
       
   573 
       
   574         // Assign to a function object allocated on the heap.
       
   575         template<typename FunctionObj>
       
   576         void 
       
   577         assign_functor(FunctionObj f, function_buffer& functor, mpl::false_)
       
   578         {
       
   579           functor.obj_ptr = new FunctionObj(f);
       
   580         }
       
   581         template<typename FunctionObj,typename Allocator>
       
   582         void 
       
   583         assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_)
       
   584         {
       
   585           typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
       
   586           typedef typename Allocator::template rebind<functor_wrapper_type>::other
       
   587             wrapper_allocator_type;
       
   588           typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
       
   589           wrapper_allocator_type wrapper_allocator(a);
       
   590           wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
       
   591           wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
       
   592           functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
       
   593           functor.obj_ptr = new_f;
       
   594         }
       
   595 
       
   596         template<typename FunctionObj>
       
   597         bool 
       
   598         assign_to(FunctionObj f, function_buffer& functor, function_obj_tag)
       
   599         {
       
   600           if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
       
   601             assign_functor(f, functor, 
       
   602                            mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
       
   603             return true;
       
   604           } else {
       
   605             return false;
       
   606           }
       
   607         }
       
   608         template<typename FunctionObj,typename Allocator>
       
   609         bool 
       
   610         assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag)
       
   611         {
       
   612           if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
       
   613             assign_functor_a(f, functor, a,
       
   614                            mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
       
   615             return true;
       
   616           } else {
       
   617             return false;
       
   618           }
       
   619         }
       
   620 
       
   621         // Reference to a function object
       
   622         template<typename FunctionObj>
       
   623         bool 
       
   624         assign_to(const reference_wrapper<FunctionObj>& f, 
       
   625                   function_buffer& functor, function_obj_ref_tag)
       
   626         {
       
   627           if (!boost::detail::function::has_empty_target(f.get_pointer())) {
       
   628             functor.obj_ref.obj_ptr = (void *)f.get_pointer();
       
   629             functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
       
   630             functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
       
   631             return true;
       
   632           } else {
       
   633             return false;
       
   634           }
       
   635         }
       
   636         template<typename FunctionObj,typename Allocator>
       
   637         bool 
       
   638         assign_to_a(const reference_wrapper<FunctionObj>& f, 
       
   639                   function_buffer& functor, Allocator, function_obj_ref_tag)
       
   640         {
       
   641           return assign_to(f,functor,function_obj_ref_tag());
       
   642         }
       
   643 
       
   644       public:
       
   645         vtable_base base;
       
   646         invoker_type invoker;
       
   647       };
       
   648     } // end namespace function
       
   649   } // end namespace detail
       
   650 
       
   651   template<
       
   652     typename R BOOST_FUNCTION_COMMA
       
   653     BOOST_FUNCTION_TEMPLATE_PARMS
       
   654   >
       
   655   class BOOST_FUNCTION_FUNCTION : public function_base
       
   656 
       
   657 #if BOOST_FUNCTION_NUM_ARGS == 1
       
   658 
       
   659     , public std::unary_function<T0,R>
       
   660 
       
   661 #elif BOOST_FUNCTION_NUM_ARGS == 2
       
   662 
       
   663     , public std::binary_function<T0,T1,R>
       
   664 
       
   665 #endif
       
   666 
       
   667   {
       
   668   public:
       
   669 #ifndef BOOST_NO_VOID_RETURNS
       
   670     typedef R         result_type;
       
   671 #else
       
   672     typedef  typename boost::detail::function::function_return_type<R>::type
       
   673       result_type;
       
   674 #endif // BOOST_NO_VOID_RETURNS
       
   675 
       
   676   private:
       
   677     typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
       
   678               R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
       
   679       vtable_type;
       
   680 
       
   681     struct clear_type {};
       
   682 
       
   683   public:
       
   684     BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
       
   685 
       
   686     // add signature for boost::lambda
       
   687     template<typename Args>
       
   688     struct sig
       
   689     {
       
   690       typedef result_type type;
       
   691     };
       
   692 
       
   693 #if BOOST_FUNCTION_NUM_ARGS == 1
       
   694     typedef T0 argument_type;
       
   695 #elif BOOST_FUNCTION_NUM_ARGS == 2
       
   696     typedef T0 first_argument_type;
       
   697     typedef T1 second_argument_type;
       
   698 #endif
       
   699 
       
   700     BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
       
   701     BOOST_FUNCTION_ARG_TYPES
       
   702 
       
   703     typedef BOOST_FUNCTION_FUNCTION self_type;
       
   704 
       
   705     BOOST_FUNCTION_FUNCTION() : function_base() { }
       
   706 
       
   707     // MSVC chokes if the following two constructors are collapsed into
       
   708     // one with a default parameter.
       
   709     template<typename Functor>
       
   710     BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
       
   711 #ifndef BOOST_NO_SFINAE
       
   712                             ,typename enable_if_c<
       
   713                             (boost::type_traits::ice_not<
       
   714                              (is_integral<Functor>::value)>::value),
       
   715                                         int>::type = 0
       
   716 #endif // BOOST_NO_SFINAE
       
   717                             ) :
       
   718       function_base()
       
   719     {
       
   720       this->assign_to(f);
       
   721     }
       
   722     template<typename Functor,typename Allocator>
       
   723     BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
       
   724 #ifndef BOOST_NO_SFINAE
       
   725                             ,typename enable_if_c<
       
   726                             (boost::type_traits::ice_not<
       
   727                              (is_integral<Functor>::value)>::value),
       
   728                                         int>::type = 0
       
   729 #endif // BOOST_NO_SFINAE
       
   730                             ) :
       
   731       function_base()
       
   732     {
       
   733       this->assign_to_a(f,a);
       
   734     }
       
   735 
       
   736 #ifndef BOOST_NO_SFINAE
       
   737     BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
       
   738 #else
       
   739     BOOST_FUNCTION_FUNCTION(int zero) : function_base()
       
   740     {
       
   741       BOOST_ASSERT(zero == 0);
       
   742     }
       
   743 #endif
       
   744 
       
   745     BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
       
   746     {
       
   747       this->assign_to_own(f);
       
   748     }
       
   749 
       
   750     ~BOOST_FUNCTION_FUNCTION() { clear(); }
       
   751 
       
   752 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
       
   753     // MSVC 6.0 and prior require all definitions to be inline, but
       
   754     // these definitions can become very costly.
       
   755     result_type operator()(BOOST_FUNCTION_PARMS) const
       
   756     {
       
   757       if (this->empty())
       
   758         boost::throw_exception(bad_function_call());
       
   759 
       
   760       return static_cast<vtable_type*>(vtable)->invoker
       
   761                (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
       
   762     }
       
   763 #else
       
   764     result_type operator()(BOOST_FUNCTION_PARMS) const;
       
   765 #endif
       
   766 
       
   767     // The distinction between when to use BOOST_FUNCTION_FUNCTION and
       
   768     // when to use self_type is obnoxious. MSVC cannot handle self_type as
       
   769     // the return type of these assignment operators, but Borland C++ cannot
       
   770     // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
       
   771     // construct.
       
   772     template<typename Functor>
       
   773 #ifndef BOOST_NO_SFINAE
       
   774     typename enable_if_c<
       
   775                (boost::type_traits::ice_not<
       
   776                  (is_integral<Functor>::value)>::value),
       
   777                BOOST_FUNCTION_FUNCTION&>::type
       
   778 #else
       
   779     BOOST_FUNCTION_FUNCTION&
       
   780 #endif
       
   781     operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
       
   782     {
       
   783       this->clear();
       
   784       try {
       
   785         this->assign_to(f);
       
   786       } catch (...) {
       
   787         vtable = 0;
       
   788         throw;
       
   789       }
       
   790       return *this;
       
   791     }
       
   792     template<typename Functor,typename Allocator>
       
   793     void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
       
   794     {
       
   795       this->clear();
       
   796       try {
       
   797         this->assign_to_a(f,a);
       
   798       } catch (...) {
       
   799         vtable = 0;
       
   800         throw;
       
   801       }
       
   802     }
       
   803 
       
   804 #ifndef BOOST_NO_SFINAE
       
   805     BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
       
   806     {
       
   807       this->clear();
       
   808       return *this;
       
   809     }
       
   810 #else
       
   811     BOOST_FUNCTION_FUNCTION& operator=(int zero)
       
   812     {
       
   813       BOOST_ASSERT(zero == 0);
       
   814       this->clear();
       
   815       return *this;
       
   816     }
       
   817 #endif
       
   818 
       
   819     // Assignment from another BOOST_FUNCTION_FUNCTION
       
   820     BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
       
   821     {
       
   822       if (&f == this)
       
   823         return *this;
       
   824 
       
   825       this->clear();
       
   826       try {
       
   827         this->assign_to_own(f);
       
   828       } catch (...) {
       
   829         vtable = 0;
       
   830         throw;
       
   831       }
       
   832       return *this;
       
   833     }
       
   834 
       
   835     void swap(BOOST_FUNCTION_FUNCTION& other)
       
   836     {
       
   837       if (&other == this)
       
   838         return;
       
   839 
       
   840       BOOST_FUNCTION_FUNCTION tmp;
       
   841       tmp.move_assign(*this);
       
   842       this->move_assign(other);
       
   843       other.move_assign(tmp);
       
   844     }
       
   845 
       
   846     // Clear out a target, if there is one
       
   847     void clear()
       
   848     {
       
   849       if (vtable) {
       
   850         reinterpret_cast<vtable_type*>(vtable)->clear(this->functor);
       
   851         vtable = 0;
       
   852       }
       
   853     }
       
   854 
       
   855 #if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
       
   856     // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
       
   857     operator bool () const { return !this->empty(); }
       
   858 #else
       
   859   private:
       
   860     struct dummy {
       
   861       void nonnull() {};
       
   862     };
       
   863 
       
   864     typedef void (dummy::*safe_bool)();
       
   865 
       
   866   public:
       
   867     operator safe_bool () const
       
   868       { return (this->empty())? 0 : &dummy::nonnull; }
       
   869 
       
   870     bool operator!() const
       
   871       { return this->empty(); }
       
   872 #endif
       
   873 
       
   874   private:
       
   875     void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
       
   876     {
       
   877       if (!f.empty()) {
       
   878         this->vtable = f.vtable;
       
   879         f.vtable->manager(f.functor, this->functor,
       
   880                           boost::detail::function::clone_functor_tag);
       
   881       }
       
   882     }
       
   883 
       
   884     template<typename Functor>
       
   885     void assign_to(Functor f)
       
   886     {
       
   887       using detail::function::vtable_base;
       
   888 
       
   889       typedef typename detail::function::get_function_tag<Functor>::type tag;
       
   890       typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
       
   891       typedef typename get_invoker::
       
   892                          template apply<Functor, R BOOST_FUNCTION_COMMA 
       
   893                         BOOST_FUNCTION_TEMPLATE_ARGS>
       
   894         handler_type;
       
   895       
       
   896       typedef typename handler_type::invoker_type invoker_type;
       
   897       typedef typename handler_type::manager_type manager_type;
       
   898 
       
   899       // Note: it is extremely important that this initialization use
       
   900       // static initialization. Otherwise, we will have a race
       
   901       // condition here in multi-threaded code. See
       
   902       // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
       
   903       static vtable_type stored_vtable = 
       
   904         { { &manager_type::manage }, &invoker_type::invoke };
       
   905 
       
   906       if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable.base;
       
   907       else vtable = 0;
       
   908     }
       
   909 
       
   910     template<typename Functor,typename Allocator>
       
   911     void assign_to_a(Functor f,Allocator a)
       
   912     {
       
   913       using detail::function::vtable_base;
       
   914 
       
   915       typedef typename detail::function::get_function_tag<Functor>::type tag;
       
   916       typedef detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
       
   917       typedef typename get_invoker::
       
   918                          template apply_a<Functor, R BOOST_FUNCTION_COMMA 
       
   919                          BOOST_FUNCTION_TEMPLATE_ARGS,
       
   920                          Allocator>
       
   921         handler_type;
       
   922       
       
   923       typedef typename handler_type::invoker_type invoker_type;
       
   924       typedef typename handler_type::manager_type manager_type;
       
   925 
       
   926       // Note: it is extremely important that this initialization use
       
   927       // static initialization. Otherwise, we will have a race
       
   928       // condition here in multi-threaded code. See
       
   929       // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
       
   930       static vtable_type stored_vtable =
       
   931         { { &manager_type::manage }, &invoker_type::invoke };
       
   932 
       
   933       if (stored_vtable.assign_to_a(f, functor, a)) vtable = &stored_vtable.base;
       
   934       else vtable = 0;
       
   935     }
       
   936 
       
   937     // Moves the value from the specified argument to *this. If the argument 
       
   938     // has its function object allocated on the heap, move_assign will pass 
       
   939     // its buffer to *this, and set the argument's buffer pointer to NULL. 
       
   940     void move_assign(BOOST_FUNCTION_FUNCTION& f) 
       
   941     { 
       
   942       if (&f == this)
       
   943         return;
       
   944 
       
   945 #if !defined(BOOST_NO_EXCEPTIONS)      
       
   946       try {
       
   947 #endif
       
   948         if (!f.empty()) {
       
   949           this->vtable = f.vtable;
       
   950           f.vtable->manager(f.functor, this->functor,
       
   951                             boost::detail::function::move_functor_tag);
       
   952 		  f.vtable = 0;
       
   953 #if !defined(BOOST_NO_EXCEPTIONS)      
       
   954         } else {
       
   955           clear();
       
   956         }
       
   957       } catch (...) {
       
   958         vtable = 0;
       
   959         throw;
       
   960       }
       
   961 #endif
       
   962     }
       
   963   };
       
   964 
       
   965   template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
       
   966   inline void swap(BOOST_FUNCTION_FUNCTION<
       
   967                      R BOOST_FUNCTION_COMMA
       
   968                      BOOST_FUNCTION_TEMPLATE_ARGS
       
   969                    >& f1,
       
   970                    BOOST_FUNCTION_FUNCTION<
       
   971                      R BOOST_FUNCTION_COMMA
       
   972                      BOOST_FUNCTION_TEMPLATE_ARGS
       
   973                    >& f2)
       
   974   {
       
   975     f1.swap(f2);
       
   976   }
       
   977 
       
   978 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
       
   979   template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
       
   980   typename BOOST_FUNCTION_FUNCTION<
       
   981       R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type
       
   982    BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
       
   983   ::operator()(BOOST_FUNCTION_PARMS) const
       
   984   {
       
   985     if (this->empty())
       
   986       boost::throw_exception(bad_function_call());
       
   987 
       
   988     return reinterpret_cast<const vtable_type*>(vtable)->invoker
       
   989              (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
       
   990   }
       
   991 #endif
       
   992 
       
   993 // Poison comparisons between boost::function objects of the same type.
       
   994 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
       
   995   void operator==(const BOOST_FUNCTION_FUNCTION<
       
   996                           R BOOST_FUNCTION_COMMA
       
   997                           BOOST_FUNCTION_TEMPLATE_ARGS>&,
       
   998                   const BOOST_FUNCTION_FUNCTION<
       
   999                           R BOOST_FUNCTION_COMMA
       
  1000                           BOOST_FUNCTION_TEMPLATE_ARGS>&);
       
  1001 template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
       
  1002   void operator!=(const BOOST_FUNCTION_FUNCTION<
       
  1003                           R BOOST_FUNCTION_COMMA
       
  1004                           BOOST_FUNCTION_TEMPLATE_ARGS>&,
       
  1005                   const BOOST_FUNCTION_FUNCTION<
       
  1006                           R BOOST_FUNCTION_COMMA
       
  1007                           BOOST_FUNCTION_TEMPLATE_ARGS>& );
       
  1008 
       
  1009 #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
       
  1010 
       
  1011 #if BOOST_FUNCTION_NUM_ARGS == 0
       
  1012 #define BOOST_FUNCTION_PARTIAL_SPEC R (void)
       
  1013 #else
       
  1014 #define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
       
  1015 #endif
       
  1016 
       
  1017 template<typename R BOOST_FUNCTION_COMMA
       
  1018          BOOST_FUNCTION_TEMPLATE_PARMS>
       
  1019 class function<BOOST_FUNCTION_PARTIAL_SPEC>
       
  1020   : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
       
  1021 {
       
  1022   typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
       
  1023   typedef function self_type;
       
  1024 
       
  1025   struct clear_type {};
       
  1026 
       
  1027 public:
       
  1028 
       
  1029   function() : base_type() {}
       
  1030 
       
  1031   template<typename Functor>
       
  1032   function(Functor f
       
  1033 #ifndef BOOST_NO_SFINAE
       
  1034            ,typename enable_if_c<
       
  1035                             (boost::type_traits::ice_not<
       
  1036                           (is_integral<Functor>::value)>::value),
       
  1037                        int>::type = 0
       
  1038 #endif
       
  1039            ) :
       
  1040     base_type(f)
       
  1041   {
       
  1042   }
       
  1043   template<typename Functor,typename Allocator>
       
  1044   function(Functor f, Allocator a
       
  1045 #ifndef BOOST_NO_SFINAE
       
  1046            ,typename enable_if_c<
       
  1047                             (boost::type_traits::ice_not<
       
  1048                           (is_integral<Functor>::value)>::value),
       
  1049                        int>::type = 0
       
  1050 #endif
       
  1051            ) :
       
  1052     base_type(f,a)
       
  1053   {
       
  1054   }
       
  1055 
       
  1056 #ifndef BOOST_NO_SFINAE
       
  1057   function(clear_type*) : base_type() {}
       
  1058 #endif
       
  1059 
       
  1060   function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
       
  1061 
       
  1062   function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
       
  1063 
       
  1064   self_type& operator=(const self_type& f)
       
  1065   {
       
  1066     self_type(f).swap(*this);
       
  1067     return *this;
       
  1068   }
       
  1069 
       
  1070   template<typename Functor>
       
  1071 #ifndef BOOST_NO_SFINAE
       
  1072   typename enable_if_c<
       
  1073                             (boost::type_traits::ice_not<
       
  1074                          (is_integral<Functor>::value)>::value),
       
  1075                       self_type&>::type
       
  1076 #else
       
  1077   self_type&
       
  1078 #endif
       
  1079   operator=(Functor f)
       
  1080   {
       
  1081     self_type(f).swap(*this);
       
  1082     return *this;
       
  1083   }
       
  1084 
       
  1085 #ifndef BOOST_NO_SFINAE
       
  1086   self_type& operator=(clear_type*)
       
  1087   {
       
  1088     this->clear();
       
  1089     return *this;
       
  1090   }
       
  1091 #endif
       
  1092 
       
  1093   self_type& operator=(const base_type& f)
       
  1094   {
       
  1095     self_type(f).swap(*this);
       
  1096     return *this;
       
  1097   }
       
  1098 };
       
  1099 
       
  1100 #undef BOOST_FUNCTION_PARTIAL_SPEC
       
  1101 #endif // have partial specialization
       
  1102 
       
  1103 } // end namespace boost
       
  1104 
       
  1105 // Cleanup after ourselves...
       
  1106 #undef BOOST_FUNCTION_VTABLE
       
  1107 #undef BOOST_FUNCTION_COMMA
       
  1108 #undef BOOST_FUNCTION_FUNCTION
       
  1109 #undef BOOST_FUNCTION_FUNCTION_INVOKER
       
  1110 #undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
       
  1111 #undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
       
  1112 #undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
       
  1113 #undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
       
  1114 #undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
       
  1115 #undef BOOST_FUNCTION_MEMBER_INVOKER
       
  1116 #undef BOOST_FUNCTION_VOID_MEMBER_INVOKER
       
  1117 #undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
       
  1118 #undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
       
  1119 #undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
       
  1120 #undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
       
  1121 #undef BOOST_FUNCTION_GET_INVOKER
       
  1122 #undef BOOST_FUNCTION_TEMPLATE_PARMS
       
  1123 #undef BOOST_FUNCTION_TEMPLATE_ARGS
       
  1124 #undef BOOST_FUNCTION_PARMS
       
  1125 #undef BOOST_FUNCTION_PARM
       
  1126 #undef BOOST_FUNCTION_ARGS
       
  1127 #undef BOOST_FUNCTION_ARG_TYPE
       
  1128 #undef BOOST_FUNCTION_ARG_TYPES
       
  1129 #undef BOOST_FUNCTION_VOID_RETURN_TYPE
       
  1130 #undef BOOST_FUNCTION_RETURN
       
  1131 
       
  1132 #if defined(BOOST_MSVC)
       
  1133 #   pragma warning( pop )
       
  1134 #endif