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