Ticket #861: has_xxx_template.patch
File has_xxx_template.patch, 43.7 KB (added by , 13 years ago) |
---|
-
boost/mpl/aux_/config/has_xxx.hpp
27 27 ) 28 28 29 29 # define BOOST_MPL_CFG_NO_HAS_XXX 30 # define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE 30 31 31 32 #endif 32 33 -
boost/mpl/has_xxx.hpp
4 4 5 5 // Copyright Aleksey Gurtovoy 2002-2006 6 6 // Copyright David Abrahams 2002-2003 7 // Copyright Daniel Walker 2007 7 8 // 8 9 // Distributed under the Boost Software License, Version 1.0. 9 10 // (See accompanying file LICENSE_1_0.txt or copy at … … 18 19 #include <boost/mpl/bool.hpp> 19 20 #include <boost/mpl/aux_/type_wrapper.hpp> 20 21 #include <boost/mpl/aux_/yes_no.hpp> 22 #include <boost/mpl/aux_/config/gcc.hpp> 21 23 #include <boost/mpl/aux_/config/has_xxx.hpp> 22 24 #include <boost/mpl/aux_/config/msvc_typename.hpp> 23 25 #include <boost/mpl/aux_/config/msvc.hpp> 24 26 #include <boost/mpl/aux_/config/static_constant.hpp> 25 27 #include <boost/mpl/aux_/config/workaround.hpp> 26 28 29 #include <boost/preprocessor/array/elem.hpp> 27 30 #include <boost/preprocessor/cat.hpp> 31 #include <boost/preprocessor/control/if.hpp> 32 #include <boost/preprocessor/repetition/enum_params.hpp> 33 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> 28 34 29 35 #if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) ) 30 36 # include <boost/type_traits/is_class.hpp> … … 271 277 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \ 272 278 /**/ 273 279 280 281 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) 282 283 // Create boolean n-ary Metafunction to detect a nested template 284 // member with n template parameters. This implementation is based on 285 // a USENET newsgroup's posting by Aleksey Gurtovoy 286 // (comp.lang.c++.moderated, 2002-03-19), Rani Sharoni's USENET 287 // posting cited above, the non-template has_xxx implementations 288 // above, and discussion on the Boost mailing list. 289 290 # if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES) 291 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 292 # define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 1 293 # endif 294 # endif 295 296 # if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION) 297 # if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) \ 298 || BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303)) 299 # define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 1 300 # endif 301 # endif 302 303 # if !defined(BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE) 304 # if BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303) 305 # define BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE 1 306 # endif 307 # endif 308 309 # if !defined(BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE) 310 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 311 # define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 1 312 # endif 313 # endif 314 315 // NOTE: All internal implementation macros take a Boost.Preprocessor 316 // array argument called args which contains the arguments passed to 317 // HAS_XXX_TEMPLATE_NAMED_DEF and is of the following form. 318 // ( 4, ( trait, name, n, default_ ) ) 319 320 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ 321 BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _introspect) \ 322 /**/ 323 324 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \ 325 BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute) \ 326 /**/ 327 328 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) \ 329 BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _test) \ 330 /**/ 331 332 // Thanks to Guillaume Melquiond for pointing out the need for the 333 // "substitute" template as an argument to the overloaded test 334 // functions to get SFINAE to work for member templates with the 335 // correct name but incorrect arguments. 336 # define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ 337 template< substitute_macro(args, V) > \ 338 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) { \ 339 }; \ 340 /**/ 341 342 # if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 343 # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ 344 template< typename V > \ 345 static boost::mpl::aux::no_tag \ 346 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \ 347 /**/ 348 # else 349 # define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ 350 static boost::mpl::aux::no_tag \ 351 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \ 352 /**/ 353 # endif 354 355 # if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 356 # define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ 357 template< typename V > \ 358 static boost::mpl::aux::yes_tag \ 359 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ 360 boost::mpl::aux::type_wrapper< V > const volatile* \ 361 , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) < \ 362 member_macro(args, V, T) \ 363 >* = 0 \ 364 ); \ 365 /**/ 366 # else 367 # define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ 368 template< typename V > \ 369 static boost::mpl::aux::yes_tag \ 370 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ 371 V const volatile* \ 372 , member_macro(args, V, T)* = 0 \ 373 ); \ 374 /**/ 375 # endif 376 377 # if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 378 # define BOOST_MPL_HAS_MEMBER_TEST(args) \ 379 sizeof(BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U >(0)) \ 380 == sizeof(boost::mpl::aux::yes_tag) \ 381 /**/ 382 # else 383 # if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 384 # define BOOST_MPL_HAS_MEMBER_TEST(args) \ 385 sizeof( \ 386 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ 387 static_cast< boost::mpl::aux::type_wrapper< U >* >(0) \ 388 ) \ 389 ) == sizeof(boost::mpl::aux::yes_tag) \ 390 /**/ 391 # else 392 # define BOOST_MPL_HAS_MEMBER_TEST(args) \ 393 sizeof( \ 394 BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \ 395 static_cast< U* >(0) \ 396 ) \ 397 ) == sizeof(boost::mpl::aux::yes_tag) \ 398 /**/ 399 # endif 400 # endif 401 402 # define BOOST_MPL_HAS_MEMBER_INTROSPECT( \ 403 args, substitute_macro, member_macro \ 404 ) \ 405 template< typename U > \ 406 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) { \ 407 BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \ 408 BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \ 409 BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \ 410 BOOST_STATIC_CONSTANT( \ 411 bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \ 412 ); \ 413 typedef boost::mpl::bool_< value > type; \ 414 }; \ 415 /**/ 416 417 # define BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ 418 args, introspect_macro, substitute_macro, member_macro \ 419 ) \ 420 template< \ 421 typename T \ 422 BOOST_PP_ENUM_TRAILING_PARAMS( \ 423 BOOST_PP_ARRAY_ELEM(2, args), typename T \ 424 ) \ 425 , typename fallback_ \ 426 = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \ 427 > \ 428 class BOOST_PP_ARRAY_ELEM(0, args) { \ 429 introspect_macro(args, substitute_macro, member_macro) \ 430 public: \ 431 static const bool value \ 432 = BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< T >::value; \ 433 typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< \ 434 T \ 435 >::type type; \ 436 }; \ 437 /**/ 438 439 // For example, 440 // BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( 441 // (4, (has_xxx, xxx, 2, false)) 442 // , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER 443 // , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS 444 // ) 445 // expands to something like the following... 446 // 447 // template< 448 // typename T , typename T0 , typename T1 449 // , typename fallback_ = boost::mpl::bool_< false > 450 // > 451 // class has_xxx { 452 // template< typename U > 453 // struct has_xxx_introspect { 454 // template< template< typename V0 , typename V1 > class V > 455 // struct has_xxx_substitute { 456 // }; 457 // 458 // template< typename V > 459 // static boost::mpl::aux::no_tag 460 // has_xxx_test(...); 461 // 462 // template< typename V > 463 // static boost::mpl::aux::yes_tag 464 // has_xxx_test( 465 // boost::mpl::aux::type_wrapper< V > const volatile* 466 // , has_xxx_substitute < V::template xxx >* = 0 467 // ); 468 // 469 // static const bool value 470 // = sizeof(has_xxx_test< U >(0)) 471 // == sizeof(boost::mpl::aux::yes_tag); 472 // typedef boost::mpl::bool_< value > type; 473 // }; 474 // public: 475 // static const bool value = has_xxx_introspect< T >::value; 476 // typedef typename has_xxx_introspect< T >::type type; 477 // }; 478 # define BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ 479 args, substitute_macro, member_macro \ 480 ) \ 481 BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ 482 args \ 483 , BOOST_MPL_HAS_MEMBER_INTROSPECT \ 484 , substitute_macro \ 485 , member_macro \ 486 ) \ 487 /**/ 488 489 # if BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 490 491 # if !defined(BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE) 492 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 493 # define BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 1 494 # endif 495 # endif 496 497 # if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 498 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ 499 args \ 500 ) \ 501 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \ 502 /**/ 503 # else 504 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ 505 args \ 506 ) \ 507 BOOST_PP_CAT( \ 508 boost_mpl_has_xxx_ \ 509 , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args) \ 510 ) \ 511 /**/ 512 # endif 513 514 # define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME( \ 515 args \ 516 ) \ 517 BOOST_PP_CAT( \ 518 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ 519 args \ 520 ) \ 521 , _tag \ 522 ) \ 523 /**/ 524 525 # define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ 526 args, substitute_macro \ 527 ) \ 528 typedef void \ 529 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \ 530 template< substitute_macro(args, U) > \ 531 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ 532 args \ 533 ) { \ 534 typedef \ 535 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ 536 type; \ 537 }; \ 538 /**/ 539 540 # define BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE( \ 541 args, member_macro \ 542 ) \ 543 template< \ 544 typename U \ 545 BOOST_PP_ENUM_TRAILING_PARAMS( \ 546 BOOST_PP_ARRAY_ELEM(2, args), typename U \ 547 ) \ 548 , typename V \ 549 = BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \ 550 > \ 551 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) { \ 552 BOOST_STATIC_CONSTANT(bool, value = false); \ 553 typedef boost::mpl::bool_< value > type; \ 554 }; \ 555 /**/ 556 557 # define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \ 558 args, member_macro \ 559 ) \ 560 template< \ 561 typename U \ 562 BOOST_PP_ENUM_TRAILING_PARAMS( \ 563 BOOST_PP_ARRAY_ELEM(2, args), typename U \ 564 ) \ 565 > \ 566 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \ 567 U BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), U) \ 568 , typename \ 569 BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \ 570 args \ 571 )< \ 572 member_macro(args, U, U) \ 573 >::type \ 574 > { \ 575 BOOST_STATIC_CONSTANT(bool, value = true); \ 576 typedef boost::mpl::bool_< value > type; \ 577 }; \ 578 /**/ 579 580 # define BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \ 581 args, substitute_macro, member_macro \ 582 ) \ 583 BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args, member_macro) \ 584 BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args, member_macro) \ 585 template< typename U > \ 586 struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \ 587 : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \ 588 U \ 589 BOOST_PP_ENUM_TRAILING_PARAMS( \ 590 BOOST_PP_ARRAY_ELEM(2, args) \ 591 , T \ 592 ) \ 593 > { \ 594 }; \ 595 /**/ 596 597 # if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 598 # define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ 599 args, substitute_macro, member_macro \ 600 ) \ 601 BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ 602 args, substitute_macro \ 603 ) \ 604 BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \ 605 args, substitute_macro, member_macro \ 606 ) \ 607 /**/ 608 # else 609 # define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \ 610 args, substitute_macro, member_macro \ 611 ) \ 612 BOOST_MPL_HAS_MEMBER_BASIC_INTROSPECT_WITH_TEMPLATE_SFINAE( \ 613 args, substitute_macro, member_macro \ 614 ) \ 615 /**/ 616 # endif 617 618 // For example, 619 // BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( 620 // (4, (has_xxx, xxx, 2, false)) 621 // , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER 622 // , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS 623 // ) 624 // expands to something like the following... 625 // 626 // template< 627 // typename T , typename T0 , typename T1 628 // , typename fallback_ = boost::mpl::bool_< false > 629 // > 630 // class has_xxx { 631 // typedef void has_xxx_substitute_tag; 632 // 633 // template< template< typename U0 , typename U1 > class U > 634 // struct has_xxx_substitute { 635 // typedef has_xxx_substitute_tag type; 636 // }; 637 // 638 // template< 639 // typename U , typename U0 , typename U1 640 // , typename V = has_xxx_substitute_tag 641 // > 642 // struct has_xxx_test { 643 // static const bool value = false; 644 // typedef boost::mpl::bool_< value > type; 645 // }; 646 // 647 // template< typename U , typename U0 , typename U1 > 648 // struct has_xxx_test< 649 // U , U0 , U1 650 // , typename has_xxx_substitute< U::template xxx >::type 651 // > { 652 // static const bool value = true; 653 // typedef boost::mpl::bool_< value > type; 654 // }; 655 // 656 // template< typename U > 657 // struct has_xxx_introspect : has_xxx_test< U , T0 , T1 > { 658 // }; 659 // public: 660 // static const bool value = has_xxx_introspect< T >::value; 661 // typedef typename has_xxx_introspect< T >::type type; 662 // }; 663 // 664 // Note that if BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is 665 // defined BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs 666 // to be expanded at namespace level before 667 // BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE can be used. 668 # define BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \ 669 args, substitute_macro, member_macro \ 670 ) \ 671 BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \ 672 args \ 673 , BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \ 674 , substitute_macro \ 675 , member_macro \ 676 ) \ 677 /**/ 678 679 # endif // BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 680 681 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER( \ 682 args, param \ 683 ) \ 684 typename \ 685 /**/ 686 687 # if !BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE 688 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_SUBSTITUTE_PARAMETER( \ 689 args, param \ 690 ) \ 691 template< \ 692 BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), typename param) \ 693 > \ 694 class param\ 695 /**/ 696 697 // See comment at BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS below. 698 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER(args, param) \ 699 BOOST_PP_IF( \ 700 BOOST_PP_ARRAY_ELEM(2, args) \ 701 , BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_SUBSTITUTE_PARAMETER \ 702 , BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER \ 703 ) ( args, param ) \ 704 /**/ 705 # else 706 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER(args, param) \ 707 BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_SUBSTITUTE_PARAMETER( \ 708 args, param \ 709 ) \ 710 /**/ 711 # endif 712 713 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS( \ 714 args, class_type, param \ 715 ) \ 716 typename class_type::template BOOST_PP_ARRAY_ELEM(1, args)< \ 717 BOOST_PP_ENUM_PARAMS(BOOST_PP_ARRAY_ELEM(2, args), param) \ 718 > \ 719 /**/ 720 721 # if !BOOST_MPL_HAS_XXX_NO_IMPLICIT_SUBSTITUTE_TEMPLATE 722 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_ACCESS( \ 723 args, class_type, param \ 724 ) \ 725 class_type::template BOOST_PP_ARRAY_ELEM(1, args) \ 726 /**/ 727 728 // Note: to recognize templates with no required arguments use 729 // explicit access since a substitute template with no args cannot be 730 // declared. 731 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS(args, class_type, param) \ 732 BOOST_PP_IF( \ 733 BOOST_PP_ARRAY_ELEM(2, args) \ 734 , BOOST_MPL_HAS_MEMBER_TEMPLATE_IMPLICIT_ACCESS \ 735 , BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS \ 736 ) ( args, class_type, param ) \ 737 /**/ 738 # else 739 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS(args, class_type, param) \ 740 BOOST_MPL_HAS_MEMBER_TEMPLATE_EXPLICIT_ACCESS( \ 741 args, class_type, param \ 742 ) \ 743 /**/ 744 # endif 745 746 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 747 // MSVC (7.1, 8.0) accepts the member template access syntax below 748 // regardless of the member template's arity. introspect will reject 749 // member templates with the wrong arity due to the substitute 750 // template. Note that using this syntax also enables MSVC 751 // template-based SFINAE to reject non-template members. This is 752 // important because explicitly passing the template args will match 753 // templates with the correct name and arguments but will cause ICE on 754 // non-template members. However, MSVC nullary template-based SFINAE 755 // (introspection for a member template with no required args) can not 756 // reject non-template members, but MSVC function-based SFINAE 757 // can. So, one of the two is chosen based on the number of required 758 // template parameters. 759 # if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) 760 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC( \ 761 args, class_type, param \ 762 ) \ 763 typename class_type::template BOOST_PP_ARRAY_ELEM(1, args)< > \ 764 /**/ 765 # else 766 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC( \ 767 args, class_type, param \ 768 ) \ 769 class_type::BOOST_PP_ARRAY_ELEM(1, agrs)< > \ 770 /**/ 771 # endif 772 773 # define BOOST_MPL_HAS_MEMBER_TEMPLATE_MSVC( \ 774 args, substitute_macro, member_macro \ 775 ) \ 776 BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \ 777 args, substitute_macro \ 778 ) \ 779 BOOST_PP_IF( \ 780 BOOST_PP_ARRAY_ELEM(2, args) \ 781 , BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE \ 782 , BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE \ 783 ) ( \ 784 args \ 785 , substitute_macro \ 786 , member_macro \ 787 ) \ 788 /**/ 789 # endif 790 791 # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 792 # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \ 793 BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \ 794 ( 4, ( trait, name, n, default_ ) ) \ 795 , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ 796 , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \ 797 ) \ 798 /**/ 799 # else 800 # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \ 801 BOOST_MPL_HAS_MEMBER_TEMPLATE_MSVC( \ 802 ( 4, ( trait, name, n, default_ ) ) \ 803 , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \ 804 , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS_MSVC \ 805 ) \ 806 /**/ 807 # endif 808 809 #else // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE 810 811 // placeholder implementation 812 813 # define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default_) \ 814 template< typename T \ 815 BOOST_PP_ENUM_TRAILING_PARAMS(n, typename U) \ 816 , typename fallback_ = boost::mpl::bool_< default_ > > \ 817 struct trait { \ 818 BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \ 819 typedef fallback_ type; \ 820 }; \ 821 /**/ 822 823 #endif // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE 824 825 # define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) \ 826 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \ 827 BOOST_PP_CAT(has_, name), name, n, false \ 828 ) \ 829 /**/ 830 274 831 #endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED -
libs/mpl/test/has_xxx.cpp
1 1 2 2 // Copyright Aleksey Gurtovoy 2000-2004 3 // Copyright Daniel Walker 2007 3 4 // 4 5 // Distributed under the Boost Software License, Version 1.0. 5 6 // (See accompanying file LICENSE_1_0.txt or copy at … … 16 17 #include <boost/mpl/aux_/test.hpp> 17 18 18 19 BOOST_MPL_HAS_XXX_TRAIT_DEF(xxx) 20 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx0, xxx, 0, false) 21 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx1, xxx, 1, false) 22 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx2, xxx, 2, false) 23 BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy0, 0) 24 BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy1, 1) 25 BOOST_MPL_HAS_XXX_TEMPLATE_DEF(yyy2, 2) 19 26 20 27 struct a1 {}; 21 28 struct a2 { void xxx(); }; … … 31 38 struct b6 { typedef void (*xxx)(); }; 32 39 struct b7 { typedef void (xxx)(); }; 33 40 41 struct c0 { template< typename T0 = int > struct xxx {}; }; 42 struct c1 { template< typename T1 > struct xxx {}; }; 43 struct c2 { template< typename T1, typename T2 > struct xxx {}; }; 44 struct c3 { template< typename T0 = int > struct yyy0 {}; }; 45 struct c4 { template< typename T1 > struct yyy1 {}; }; 46 struct c5 { template< typename T1, typename T2 > struct yyy2 {}; }; 47 34 48 template< typename T > struct outer; 35 49 template< typename T > struct inner { typedef typename T::type type; }; 36 50 … … 42 56 MPL_TEST_CASE() 43 57 { 44 58 MPL_ASSERT_NOT(( has_xxx<int> )); 59 MPL_ASSERT_NOT(( has_xxx0< int > )); 60 MPL_ASSERT_NOT(( has_xxx1< int, int > )); 61 MPL_ASSERT_NOT(( has_xxx2< int, int, int > )); 62 MPL_ASSERT_NOT(( has_yyy0< int > )); 63 MPL_ASSERT_NOT(( has_yyy1< int, int > )); 64 MPL_ASSERT_NOT(( has_yyy2< int, int, int > )); 65 45 66 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) 46 67 MPL_ASSERT_NOT(( has_xxx<int&> )); 68 MPL_ASSERT_NOT(( has_xxx0< int& > )); 69 MPL_ASSERT_NOT(( has_xxx1< int&, int > )); 70 MPL_ASSERT_NOT(( has_xxx2< int&, int, int > )); 71 MPL_ASSERT_NOT(( has_yyy0< int& > )); 72 MPL_ASSERT_NOT(( has_yyy1< int&, int > )); 73 MPL_ASSERT_NOT(( has_yyy2< int&, int, int > )); 74 47 75 MPL_ASSERT_NOT(( has_xxx<int*> )); 76 MPL_ASSERT_NOT(( has_xxx0< int* > )); 77 MPL_ASSERT_NOT(( has_xxx1< int*, int > )); 78 MPL_ASSERT_NOT(( has_xxx2< int*, int, int > )); 79 MPL_ASSERT_NOT(( has_yyy0< int* > )); 80 MPL_ASSERT_NOT(( has_yyy1< int*, int > )); 81 MPL_ASSERT_NOT(( has_yyy2< int*, int, int > )); 82 48 83 MPL_ASSERT_NOT(( has_xxx<int[]> )); 84 MPL_ASSERT_NOT(( has_xxx0< int[] > )); 85 MPL_ASSERT_NOT(( has_xxx1< int[], int > )); 86 MPL_ASSERT_NOT(( has_xxx2< int[], int, int > )); 87 MPL_ASSERT_NOT(( has_yyy0< int[] > )); 88 MPL_ASSERT_NOT(( has_yyy1< int[], int > )); 89 MPL_ASSERT_NOT(( has_yyy2< int[], int, int > )); 90 49 91 MPL_ASSERT_NOT(( has_xxx<int (*)()> )); 92 MPL_ASSERT_NOT(( has_xxx0< int (*)() > )); 93 MPL_ASSERT_NOT(( has_xxx1< int (*)(), int > )); 94 MPL_ASSERT_NOT(( has_xxx2< int (*)(), int, int > )); 95 MPL_ASSERT_NOT(( has_yyy0< int (*)() > )); 96 MPL_ASSERT_NOT(( has_yyy1< int (*)(), int > )); 97 MPL_ASSERT_NOT(( has_yyy2< int (*)(), int, int > )); 50 98 51 99 MPL_ASSERT_NOT(( has_xxx<a2> )); 100 MPL_ASSERT_NOT(( has_xxx0< a2 > )); 101 MPL_ASSERT_NOT(( has_xxx1< a2, int > )); 102 MPL_ASSERT_NOT(( has_xxx2< a2, int, int > )); 103 MPL_ASSERT_NOT(( has_yyy0< a2 > )); 104 MPL_ASSERT_NOT(( has_yyy1< a2, int > )); 105 MPL_ASSERT_NOT(( has_yyy2< a2, int, int > )); 106 52 107 MPL_ASSERT_NOT(( has_xxx<a3> )); 108 MPL_ASSERT_NOT(( has_xxx0< a3 > )); 109 MPL_ASSERT_NOT(( has_xxx1< a3, int > )); 110 MPL_ASSERT_NOT(( has_xxx2< a3, int, int > )); 111 MPL_ASSERT_NOT(( has_yyy0< a3 > )); 112 MPL_ASSERT_NOT(( has_yyy1< a3, int > )); 113 MPL_ASSERT_NOT(( has_yyy2< a3, int, int > )); 114 53 115 MPL_ASSERT_NOT(( has_xxx<a4> )); 116 MPL_ASSERT_NOT(( has_xxx0< a4 > )); 117 MPL_ASSERT_NOT(( has_xxx1< a4, int > )); 118 MPL_ASSERT_NOT(( has_xxx2< a4, int, int > )); 119 MPL_ASSERT_NOT(( has_yyy0< a4 > )); 120 MPL_ASSERT_NOT(( has_yyy1< a4, int > )); 121 MPL_ASSERT_NOT(( has_yyy2< a4, int, int > )); 122 54 123 #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) 55 124 MPL_ASSERT_NOT(( has_xxx<a5> )); 56 125 #endif 57 126 MPL_ASSERT_NOT(( has_xxx< enum_ > )); 127 MPL_ASSERT_NOT(( has_xxx0< enum_ > )); 128 MPL_ASSERT_NOT(( has_xxx1< enum_, int > )); 129 MPL_ASSERT_NOT(( has_xxx2< enum_, int, int > )); 130 MPL_ASSERT_NOT(( has_yyy0< enum_ > )); 131 MPL_ASSERT_NOT(( has_yyy1< enum_, int > )); 132 MPL_ASSERT_NOT(( has_yyy2< enum_, int, int > )); 58 133 #endif 134 59 135 MPL_ASSERT_NOT(( has_xxx<a1> )); 136 MPL_ASSERT_NOT(( has_xxx0< a1 > )); 137 MPL_ASSERT_NOT(( has_xxx1< a1, int > )); 138 MPL_ASSERT_NOT(( has_xxx2< a1, int, int > )); 139 MPL_ASSERT_NOT(( has_yyy0< a1 > )); 140 MPL_ASSERT_NOT(( has_yyy1< a1, int > )); 141 MPL_ASSERT_NOT(( has_yyy2< a1, int, int > )); 142 60 143 MPL_ASSERT_NOT(( has_xxx< outer< inner<int> > > )); 144 MPL_ASSERT_NOT(( has_xxx0< outer< inner<int> > > )); 145 MPL_ASSERT_NOT(( has_xxx1< outer< inner<int> >, int > )); 146 MPL_ASSERT_NOT(( has_xxx2< outer< inner<int> >, int, int > )); 147 MPL_ASSERT_NOT(( has_yyy0< outer< inner<int> > > )); 148 MPL_ASSERT_NOT(( has_yyy1< outer< inner<int> >, int > )); 149 MPL_ASSERT_NOT(( has_yyy2< outer< inner<int> >, int, int > )); 150 61 151 MPL_ASSERT_NOT(( has_xxx< incomplete > )); 152 MPL_ASSERT_NOT(( has_xxx0< incomplete > )); 153 MPL_ASSERT_NOT(( has_xxx1< incomplete, int > )); 154 MPL_ASSERT_NOT(( has_xxx2< incomplete, int, int > )); 155 MPL_ASSERT_NOT(( has_yyy0< incomplete > )); 156 MPL_ASSERT_NOT(( has_yyy1< incomplete, int > )); 157 MPL_ASSERT_NOT(( has_yyy2< incomplete, int, int > )); 158 62 159 MPL_ASSERT_NOT(( has_xxx< abstract > )); 160 MPL_ASSERT_NOT(( has_xxx0< abstract > )); 161 MPL_ASSERT_NOT(( has_xxx1< abstract, int > )); 162 MPL_ASSERT_NOT(( has_xxx2< abstract, int, int > )); 163 MPL_ASSERT_NOT(( has_yyy0< abstract > )); 164 MPL_ASSERT_NOT(( has_yyy1< abstract, int > )); 165 MPL_ASSERT_NOT(( has_yyy2< abstract, int, int > )); 166 63 167 MPL_ASSERT_NOT(( has_xxx< noncopyable > )); 168 MPL_ASSERT_NOT(( has_xxx0< noncopyable > )); 169 MPL_ASSERT_NOT(( has_xxx1< noncopyable, int > )); 170 MPL_ASSERT_NOT(( has_xxx2< noncopyable, int, int > )); 171 MPL_ASSERT_NOT(( has_yyy0< noncopyable > )); 172 MPL_ASSERT_NOT(( has_yyy1< noncopyable, int > )); 173 MPL_ASSERT_NOT(( has_yyy2< noncopyable, int, int > )); 64 174 175 #if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) 176 MPL_ASSERT_NOT(( has_xxx0< b1 > )); 177 MPL_ASSERT_NOT(( has_xxx1< b1, int > )); 178 MPL_ASSERT_NOT(( has_xxx2< b1, int, int > )); 179 MPL_ASSERT_NOT(( has_yyy0< b1 > )); 180 MPL_ASSERT_NOT(( has_yyy1< b1, int > )); 181 MPL_ASSERT_NOT(( has_yyy2< b1, int, int > )); 182 183 MPL_ASSERT_NOT(( has_xxx0< b2 > )); 184 MPL_ASSERT_NOT(( has_xxx1< b2, int > )); 185 MPL_ASSERT_NOT(( has_xxx2< b2, int, int > )); 186 MPL_ASSERT_NOT(( has_yyy0< b2 > )); 187 MPL_ASSERT_NOT(( has_yyy1< b2, int > )); 188 MPL_ASSERT_NOT(( has_yyy2< b2, int, int > )); 189 190 MPL_ASSERT_NOT(( has_xxx0< b3 > )); 191 MPL_ASSERT_NOT(( has_xxx1< b3, int > )); 192 MPL_ASSERT_NOT(( has_xxx2< b3, int, int > )); 193 MPL_ASSERT_NOT(( has_yyy0< b3 > )); 194 MPL_ASSERT_NOT(( has_yyy1< b3, int > )); 195 MPL_ASSERT_NOT(( has_yyy2< b3, int, int > )); 196 197 MPL_ASSERT_NOT(( has_xxx0< b4 > )); 198 MPL_ASSERT_NOT(( has_xxx1< b4, int > )); 199 MPL_ASSERT_NOT(( has_xxx2< b4, int, int > )); 200 MPL_ASSERT_NOT(( has_yyy0< b4 > )); 201 MPL_ASSERT_NOT(( has_yyy1< b4, int > )); 202 MPL_ASSERT_NOT(( has_yyy2< b4, int, int > )); 203 204 MPL_ASSERT_NOT(( has_xxx0< b5 > )); 205 MPL_ASSERT_NOT(( has_xxx1< b5, int > )); 206 MPL_ASSERT_NOT(( has_xxx2< b5, int, int > )); 207 MPL_ASSERT_NOT(( has_yyy0< b5 > )); 208 MPL_ASSERT_NOT(( has_yyy1< b5, int > )); 209 MPL_ASSERT_NOT(( has_yyy2< b5, int, int > )); 210 211 MPL_ASSERT_NOT(( has_xxx0< b6 > )); 212 MPL_ASSERT_NOT(( has_xxx1< b6, int > )); 213 MPL_ASSERT_NOT(( has_xxx2< b6, int, int > )); 214 MPL_ASSERT_NOT(( has_yyy0< b6 > )); 215 MPL_ASSERT_NOT(( has_yyy1< b6, int > )); 216 MPL_ASSERT_NOT(( has_yyy2< b6, int, int > )); 217 218 MPL_ASSERT_NOT(( has_xxx0< b7 > )); 219 MPL_ASSERT_NOT(( has_xxx1< b7, int > )); 220 MPL_ASSERT_NOT(( has_xxx2< b7, int, int > )); 221 MPL_ASSERT_NOT(( has_yyy0< b7 > )); 222 MPL_ASSERT_NOT(( has_yyy1< b7, int > )); 223 MPL_ASSERT_NOT(( has_yyy2< b7, int, int > )); 224 #endif 225 226 // Same name, different args. 227 // Note: has_xxx0 is not test here because it's impossible to 228 // declare a template with no arguments (only no required 229 // arguments), so there is no zero argument substitute template 230 // to reject n-ary member templates. 231 #if (!BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, <= 0x0303) \ 232 && !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308))) 233 MPL_ASSERT_NOT(( has_xxx1<c2, int> )); 234 MPL_ASSERT_NOT(( has_xxx2<c0, int, int> )); 235 MPL_ASSERT_NOT(( has_xxx2<c1, int, int> )); 236 #endif 237 238 // Different name, same args. 239 MPL_ASSERT_NOT(( has_xxx0<c3> )); 240 MPL_ASSERT_NOT(( has_xxx1<c4, int> )); 241 MPL_ASSERT_NOT(( has_xxx2<c5, int, int> )); 242 243 // Different name, different args. 244 MPL_ASSERT_NOT(( has_xxx0<c4> )); 245 MPL_ASSERT_NOT(( has_xxx1<c5, int> )); 246 MPL_ASSERT_NOT(( has_xxx2<c3, int, int> )); 247 MPL_ASSERT_NOT(( has_xxx2<c4, int, int> )); 248 65 249 MPL_ASSERT(( has_xxx<b1,true_> )); 66 250 MPL_ASSERT(( has_xxx<b2,true_> )); 67 251 MPL_ASSERT(( has_xxx<b3,true_> )); … … 70 254 MPL_ASSERT(( has_xxx<b6,true_> )); 71 255 MPL_ASSERT(( has_xxx<b7,true_> )); 72 256 257 #if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) && !BOOST_WORKAROUND(BOOST_MSVC, == 1500) 258 MPL_ASSERT(( has_xxx0<c0, true_> )); 259 MPL_ASSERT(( has_yyy0<c3, true_> )); 260 #endif 261 MPL_ASSERT(( has_xxx1<c1, int, true_> )); 262 MPL_ASSERT(( has_xxx2<c2, int, int, true_> )); 263 MPL_ASSERT(( has_yyy1<c4, int, true_> )); 264 MPL_ASSERT(( has_yyy2<c5, int, int, true_> )); 265 73 266 #if !defined(HAS_XXX_ASSERT) 74 267 # define HAS_XXX_ASSERT(x) MPL_ASSERT(x) 75 268 #endif … … 81 274 HAS_XXX_ASSERT(( has_xxx<b5> )); 82 275 HAS_XXX_ASSERT(( has_xxx<b6> )); 83 276 HAS_XXX_ASSERT(( has_xxx<b7> )); 277 278 #if !defined(HAS_XXX_TEMPLATE_ASSERT) 279 # define HAS_XXX_TEMPLATE_ASSERT(x) MPL_ASSERT(x) 280 #endif 281 282 #if !BOOST_WORKAROUND(__COMO_VERSION__, BOOST_TESTED_AT(4308)) && !BOOST_WORKAROUND(BOOST_MSVC, == 1500) 283 HAS_XXX_TEMPLATE_ASSERT(( has_xxx0<c0> )); 284 HAS_XXX_TEMPLATE_ASSERT(( has_yyy0<c3> )); 285 #endif 286 HAS_XXX_TEMPLATE_ASSERT(( has_xxx1<c1, int> )); 287 HAS_XXX_TEMPLATE_ASSERT(( has_xxx2<c2, int, int> )); 288 HAS_XXX_TEMPLATE_ASSERT(( has_yyy1<c4, int> )); 289 HAS_XXX_TEMPLATE_ASSERT(( has_yyy2<c5, int, int> )); 84 290 } -
libs/mpl/test/no_has_xxx.cpp
23 23 # define HAS_XXX_ASSERT(x) MPL_ASSERT_NOT(x) 24 24 #endif 25 25 26 #if defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) 27 # define HAS_XXX_TEMPLATE_ASSERT(x) MPL_ASSERT_NOT(x) 28 #endif 29 26 30 #include "has_xxx.cpp" -
libs/mpl/doc/src/refmanual/CFG_NO_HAS_XXX_TEMPLATE.rst
1 .. Macros/Configuration//BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE |20 2 3 .. Copyright Daniel Walker 2007. 4 .. Distributed under the Boost 5 .. Software License, Version 1.0. (See accompanying 6 .. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE 9 ======================== 10 11 Synopsis 12 -------- 13 14 .. parsed-literal:: 15 16 // #define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE 17 18 19 Description 20 ----------- 21 22 ``BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE`` is a boolean configuration 23 macro signaling availability of the |BOOST_MPL_HAS_XXX_TEMPLATE_DEF| / 24 |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF| introspection macros' 25 functionality on a particular compiler. 26 27 28 See also 29 -------- 30 31 |Macros|, |Configuration|, |BOOST_MPL_HAS_XXX_TEMPLATE_DEF|, |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF| 32 -
libs/mpl/doc/src/refmanual/HAS_XXX_TEMPLATE_NAMED_DEF.rst
Property changes on: libs\mpl\doc\src\refmanual\CFG_NO_HAS_XXX_TEMPLATE.rst ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Id Added: svn:eol-style + native
1 .. Macros/Introspection//BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF 2 3 .. Copyright Daniel Walker 2007. 4 .. Distributed under the Boost 5 .. Software License, Version 1.0. (See accompanying 6 .. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF 9 ================================= 10 11 Synopsis 12 -------- 13 14 .. parsed-literal:: 15 16 #define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, default\_) \\ 17 |unspecified-token-seq| \\ 18 /\*\*/ 19 20 21 Description 22 ----------- 23 24 Expands into the definition of a boolean n-ary |Metafunction| ``trait`` 25 such that for any types ``x, a1, a2, ..., an`` ``trait<x, a1, ..., 26 an>::value == true`` if and only if ``x`` is a class type and has a 27 nested template member ``x::template name<a1, ..., an>``. 28 29 On deficient compilers not capable of performing the detection, 30 ``trait<x, a1, ..., an>::value`` always returns a fallback value 31 ``default_``. A boolean configuration macro, 32 |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is provided to signal or override 33 the "deficient" status of a particular compiler. |Note:| The fallback 34 value can also be provided at the point of the metafunction 35 invocation; see the `Expression semantics` section for details |-- end 36 note| 37 38 39 Header 40 ------ 41 42 .. parsed-literal:: 43 44 #include <boost/mpl/has_xxx.hpp> 45 46 47 Parameters 48 ---------- 49 50 +---------------+-------------------------------+---------------------------------------------------+ 51 | Parameter | Requirement | Description | 52 +===============+===============================+===================================================+ 53 | ``trait`` | A legal identifier token | A name of the metafunction to be generated. | 54 +---------------+-------------------------------+---------------------------------------------------+ 55 | ``name`` | A legal identifier token | A name of the member being detected. | 56 +---------------+-------------------------------+---------------------------------------------------+ 57 | ``n`` | An integral constant >= 0 | The arity of the template member being detected. | 58 +---------------+-------------------------------+---------------------------------------------------+ 59 | ``default_`` | An boolean constant | A fallback value for the deficient compilers. | 60 +---------------+-------------------------------+---------------------------------------------------+ 61 62 63 Expression semantics 64 -------------------- 65 66 For any legal C++ identifiers ``trait`` and ``name``, integral 67 constant expression ``n`` greater than or equal to 0, boolean constant 68 expression ``c1``, boolean |Integral Constant| ``c2``, and arbitrary 69 type ``x``: 70 71 .. parsed-literal:: 72 73 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, n, c1) 74 75 :Precondition: 76 Appears at namespace scope. 77 78 :Return type: 79 None. 80 81 :Semantics: 82 Expands into an equivalent of the following class template 83 definition 84 85 .. parsed-literal:: 86 87 template< 88 typename X 89 , typename A1, ..., typename An 90 , typename fallback = boost::mpl::bool_<c1> 91 > 92 struct trait 93 { 94 // |unspecified| 95 // ... 96 }; 97 98 where ``trait`` is a boolean |Metafunction| with the following 99 semantics: 100 101 .. parsed-literal:: 102 103 typedef trait<x, a1, ..., an>::type r; 104 105 :Return type: 106 |Integral Constant|. 107 108 :Semantics: 109 If |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| is defined, ``r::value 110 == c1``; otherwise, ``r::value == true`` if and only if ``x`` 111 is a class type that has a nested type member ``x::template 112 name<a1, ..., an>``. 113 114 115 .. parsed-literal:: 116 117 typedef trait< x, a1, ..., an, c2 >::type r; 118 119 :Return type: 120 |Integral Constant|. 121 122 :Semantics: 123 If |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| is defined, ``r::value 124 == c2::value``; otherwise, equivalent to 125 126 .. parsed-literal:: 127 128 typedef trait<x, a1, ..., an>::type r; 129 130 131 Example 132 ------- 133 134 .. parsed-literal:: 135 136 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( 137 has_xxx, xxx, 1, false 138 ) 139 140 struct test1 {}; 141 struct test2 { void xxx(); }; 142 struct test3 { int xxx; }; 143 struct test4 { static int xxx(); }; 144 struct test5 { typedef int xxx; }; 145 struct test6 { struct xxx; }; 146 struct test7 { typedef void (*xxx)(); }; 147 struct test8 { typedef void (xxx)(); }; 148 struct test9 { template< class T > struct xxx {}; }; 149 150 BOOST_MPL_ASSERT_NOT(( has_xxx<test1, int> )); 151 BOOST_MPL_ASSERT_NOT(( has_xxx<test2, int> )); 152 BOOST_MPL_ASSERT_NOT(( has_xxx<test3, int> )); 153 BOOST_MPL_ASSERT_NOT(( has_xxx<test4, int> )); 154 BOOST_MPL_ASSERT_NOT(( has_xxx<test5, int> )); 155 BOOST_MPL_ASSERT_NOT(( has_xxx<test6, int> )); 156 BOOST_MPL_ASSERT_NOT(( has_xxx<test7, int> )); 157 BOOST_MPL_ASSERT_NOT(( has_xxx<test8, int> )); 158 159 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) 160 BOOST_MPL_ASSERT(( has_xxx<test9, int> )); 161 #endif 162 163 BOOST_MPL_ASSERT(( has_xxx<test9, int, true_> )); 164 165 166 See also 167 -------- 168 169 |Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_DEF|, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| 170 -
libs/mpl/doc/src/refmanual/HAS_XXX_TEMPLATE_DEF.rst
Property changes on: libs\mpl\doc\src\refmanual\HAS_XXX_TEMPLATE_NAMED_DEF.rst ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Id Added: svn:eol-style + native
1 .. Macros/Introspection//BOOST_MPL_HAS_XXX_TEMPLATE_DEF 2 3 .. Copyright Daniel Walker 2007. 4 .. Distributed under the Boost 5 .. Software License, Version 1.0. (See accompanying 6 .. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 BOOST_MPL_HAS_XXX_TEMPLATE_DEF 9 =========================== 10 11 Synopsis 12 -------- 13 14 .. parsed-literal:: 15 16 #define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) \\ 17 |unspecified-token-seq| \\ 18 /\*\*/ 19 20 21 Description 22 ----------- 23 24 Expands into the definition of a boolean n-ary |Metafunction| 25 ``has_name`` such that for any types ``x, a1, a2, ..., an`` 26 ``has_name<x, a1, ..., an>::value == true`` if and only if ``x`` is a 27 class type and has a nested template member ``x::template name<a1, 28 ..., an>``. 29 30 On deficient compilers not capable of performing the detection, 31 ``has_name<x, a1, ..., an>::value`` always returns ``false``. A 32 boolean configuration macro, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE|, is 33 provided to signal or override the "deficient" status of a particular 34 compiler. 35 36 |Note:| |BOOST_MPL_HAS_XXX_TEMPLATE_DEF| is a simplified front end to 37 the |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF| introspection macro |-- end 38 note| 39 40 41 Header 42 ------ 43 44 .. parsed-literal:: 45 46 #include <boost/mpl/has_xxx.hpp> 47 48 49 Parameters 50 ---------- 51 52 53 +---------------+-------------------------------+---------------------------------------------------+ 54 | Parameter | Requirement | Description | 55 +===============+===============================+===================================================+ 56 | ``name`` | A legal identifier token | A name of the template member being detected. | 57 +---------------+-------------------------------+---------------------------------------------------+ 58 | ``n`` | An integral constant >= 0 | The arity of the template member being detected. | 59 +---------------+-------------------------------+---------------------------------------------------+ 60 61 62 Expression semantics 63 -------------------- 64 65 For any legal C++ identifier ``name`` and integral constant expression 66 ``n`` greater than or equal to 0: 67 68 .. parsed-literal:: 69 70 BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name, n) 71 72 :Precondition: 73 Appears at namespace scope. 74 75 :Return type: 76 None. 77 78 :Semantics: 79 Equivalent to 80 81 .. parsed-literal:: 82 83 BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( 84 BOOST_PP_CAT(has\_,name), name, n, false 85 ) 86 87 88 Example 89 ------- 90 91 .. parsed-literal:: 92 93 BOOST_MPL_HAS_XXX_TEMPLATE_DEF(xxx, 1) 94 95 struct test1 {}; 96 struct test2 { void xxx(); }; 97 struct test3 { int xxx; }; 98 struct test4 { static int xxx(); }; 99 struct test5 { typedef int xxx; }; 100 struct test6 { struct xxx; }; 101 struct test7 { typedef void (*xxx)(); }; 102 struct test8 { typedef void (xxx)(); }; 103 struct test9 { template< class T > struct xxx {}; }; 104 105 BOOST_MPL_ASSERT_NOT(( has_xxx<test1, int> )); 106 BOOST_MPL_ASSERT_NOT(( has_xxx<test2, int> )); 107 BOOST_MPL_ASSERT_NOT(( has_xxx<test3, int> )); 108 BOOST_MPL_ASSERT_NOT(( has_xxx<test4, int> )); 109 BOOST_MPL_ASSERT_NOT(( has_xxx<test5, int> )); 110 BOOST_MPL_ASSERT_NOT(( has_xxx<test6, int> )); 111 BOOST_MPL_ASSERT_NOT(( has_xxx<test7, int> )); 112 BOOST_MPL_ASSERT_NOT(( has_xxx<test8, int> )); 113 114 #if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE) 115 BOOST_MPL_ASSERT(( has_xxx<test9, int> )); 116 #endif 117 118 BOOST_MPL_ASSERT(( has_xxx<test9, int, true_> )); 119 120 121 See also 122 -------- 123 124 |Macros|, |BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF|, |BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE| 125