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