File indexing completed on 2025-01-18 09:30:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
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 )
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
0042 #if BOOST_FUNCTION_NUM_ARGS == 0
0043 # define BOOST_FUNCTION_COMMA
0044 #else
0045 # define BOOST_FUNCTION_COMMA ,
0046 #endif
0047
0048
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
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
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
0323
0324
0325
0326
0327
0328
0329
0330
0331 template<typename Tag>
0332 struct BOOST_FUNCTION_GET_INVOKER { };
0333
0334
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
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
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
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
0471
0472
0473
0474
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
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
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
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
0525
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
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
0545
0546
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
0558
0559
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
0568
0569
0570
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
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
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 }
0664 }
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
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
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
0717
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
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
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
0776
0777
0778
0779
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
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
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
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
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
0911
0912 # if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
0913 # pragma GCC diagnostic push
0914
0915
0916 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
0917 # if (BOOST_GCC >= 110000)
0918
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
0948
0949
0950
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
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
0982
0983
0984
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
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
1001
1002
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
1013
1014 # if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
1015 # pragma GCC diagnostic push
1016
1017
1018 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1019 # if (BOOST_GCC >= 120000)
1020
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
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
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
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
1192
1193 }
1194
1195
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