1 // Copyright David Abrahams, Daniel Wallin 2003. Use, modification and 2 // distribution is subject to the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 #ifndef BOOST_PARAMETERS_031014_HPP 7 #define BOOST_PARAMETERS_031014_HPP 8 9 #include <boost/detail/is_xxx.hpp> 10 11 #include <boost/type_traits/is_const.hpp> 12 13 #include <boost/mpl/lambda.hpp> 14 #include <boost/mpl/apply.hpp> 15 #include <boost/mpl/always.hpp> 16 #include <boost/mpl/and.hpp> 17 #include <boost/mpl/or.hpp> 18 #include <boost/mpl/if.hpp> 19 #include <boost/mpl/identity.hpp> 20 #include <boost/mpl/not.hpp> 21 #include <boost/mpl/eval_if.hpp> 22 #include <boost/mpl/pair.hpp> 23 24 #include <boost/type_traits/is_same.hpp> 25 #include <boost/type_traits/remove_reference.hpp> 26 27 #include <boost/preprocessor/repetition/enum.hpp> 28 #include <boost/preprocessor/repetition/enum_params.hpp> 29 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> 30 #include <boost/preprocessor/arithmetic/sub.hpp> 31 #include <boost/preprocessor/repetition/repeat.hpp> 32 #include <boost/preprocessor/repetition/enum_shifted.hpp> 33 #include <boost/preprocessor/repetition/enum_binary_params.hpp> 34 #include <boost/preprocessor/repetition/enum_shifted_params.hpp> 35 #include <boost/preprocessor/seq/elem.hpp> 36 #include <boost/preprocessor/iteration/iterate.hpp> 37 #include <boost/preprocessor/facilities/intercept.hpp> 38 #include <boost/preprocessor/cat.hpp> 39 40 #include <boost/parameter/aux_/arg_list.hpp> 41 #include <boost/parameter/aux_/yesno.hpp> 42 #include <boost/parameter/aux_/void.hpp> 43 #include <boost/parameter/aux_/default.hpp> 44 #include <boost/parameter/aux_/unwrap_cv_reference.hpp> 45 #include <boost/parameter/aux_/tagged_argument.hpp> 46 #include <boost/parameter/aux_/tag.hpp> 47 #include <boost/parameter/aux_/template_keyword.hpp> 48 #include <boost/parameter/aux_/set.hpp> 49 #include <boost/parameter/config.hpp> 50 51 namespace parameter_ 52 { 53 template <class T> 54 struct unmatched_argument 55 { 56 BOOST_MPL_ASSERT((boost::is_same<T,void>)); 57 typedef int type; 58 }; 59 } // namespace parameter_ 60 61 namespace boost { 62 63 template<class T> class reference_wrapper; 64 65 namespace parameter { 66 67 namespace aux { struct use_default {}; } 68 69 // These templates can be used to describe the treatment of particular 70 // named parameters for the purposes of overload elimination with 71 // SFINAE, by placing specializations in the parameters<...> list. In 72 // order for a treated function to participate in overload resolution: 73 // 74 // - all keyword tags wrapped in required<...> must have a matching 75 // actual argument 76 // 77 // - The actual argument type matched by every keyword tag 78 // associated with a predicate must satisfy that predicate 79 // 80 // If a keyword k is specified without an optional<...> or 81 // required<...>, wrapper, it is treated as though optional<k> were 82 // specified. 83 // 84 // If a keyword k is specified with deduced<...>, that keyword 85 // will be automatically deduced from the argument list. 86 // 87 template <class Tag, class Predicate = aux::use_default> 88 struct required 89 { 90 typedef Tag key_type; 91 typedef Predicate predicate; 92 }; 93 94 template <class Tag, class Predicate = aux::use_default> 95 struct optional 96 { 97 typedef Tag key_type; 98 typedef Predicate predicate; 99 }; 100 101 template <class Tag> 102 struct deduced 103 { 104 typedef Tag key_type; 105 }; 106 107 namespace aux 108 { 109 // Defines metafunctions, is_required and is_optional, that 110 // identify required<...>, optional<...> and deduced<...> specializations. 111 BOOST_DETAIL_IS_XXX_DEF(required, required, 2) 112 BOOST_DETAIL_IS_XXX_DEF(optional, optional, 2) 113 BOOST_DETAIL_IS_XXX_DEF(deduced_aux, deduced, 1) 114 115 template <class S> 116 struct is_deduced0 117 : is_deduced_aux< 118 typename S::key_type 119 >::type 120 {}; 121 122 template <class S> 123 struct is_deduced 124 : mpl::eval_if< 125 mpl::or_< 126 is_optional<S>, is_required<S> 127 > 128 , is_deduced0<S> 129 , mpl::false_ 130 >::type 131 {}; 132 133 // 134 // key_type, has_default, and predicate -- 135 // 136 // These metafunctions accept a ParameterSpec and extract the 137 // keyword tag, whether or not a default is supplied for the 138 // parameter, and the predicate that the corresponding actual 139 // argument type is required match. 140 // 141 // a ParameterSpec is a specialization of either keyword<...>, 142 // required<...>, optional<...> 143 // 144 145 // helper for key_type<...>, below. 146 template <class T> 147 struct get_tag_type0 148 { 149 typedef typename T::key_type type; 150 }; 151 152 template <class T> 153 struct get_tag_type 154 : mpl::eval_if< 155 is_deduced_aux<typename T::key_type> 156 , get_tag_type0<typename T::key_type> 157 , mpl::identity<typename T::key_type> 158 > 159 {}; 160 161 template <class T> 162 struct tag_type 163 : mpl::eval_if< 164 mpl::or_< 165 is_optional<T> 166 , is_required<T> 167 > 168 , get_tag_type<T> 169 , mpl::identity<T> 170 > 171 {}; 172 173 template <class T> 174 struct has_default 175 : mpl::not_<is_required<T> > 176 {}; 177 178 // helper for get_predicate<...>, below 179 template <class T> 180 struct get_predicate_or_default 181 { 182 typedef T type; 183 }; 184 185 template <> 186 struct get_predicate_or_default<use_default> 187 { 188 typedef mpl::always<mpl::true_> type; 189 }; 190 191 // helper for predicate<...>, below 192 template <class T> 193 struct get_predicate 194 { 195 typedef typename 196 get_predicate_or_default<typename T::predicate>::type 197 type; 198 }; 199 200 template <class T> 201 struct predicate 202 : mpl::eval_if< 203 mpl::or_< 204 is_optional<T> 205 , is_required<T> 206 > 207 , get_predicate<T> 208 , mpl::identity<mpl::always<mpl::true_> > 209 > 210 { 211 }; 212 213 214 // Converts a ParameterSpec into a specialization of 215 // parameter_requirements. We need to do this in order to get the 216 // tag_type into the type in a way that can be conveniently matched 217 // by a satisfies(...) member function in arg_list. 218 template <class ParameterSpec> 219 struct as_parameter_requirements 220 { 221 typedef parameter_requirements< 222 typename tag_type<ParameterSpec>::type 223 , typename predicate<ParameterSpec>::type 224 , typename has_default<ParameterSpec>::type 225 > type; 226 }; 227 228 template <class T> 229 struct is_named_argument 230 : mpl::or_< 231 is_template_keyword<T> 232 , is_tagged_argument<T> 233 > 234 {}; 235 236 // Returns mpl::true_ iff the given ParameterRequirements are 237 // satisfied by ArgList. 238 template <class ArgList, class ParameterRequirements> 239 struct satisfies 240 { 241 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) 242 // VC7.1 can't handle the sizeof() implementation below, 243 // so we use this instead. 244 typedef typename mpl::apply_wrap3< 245 typename ArgList::binding 246 , typename ParameterRequirements::keyword 247 , void_ 248 , mpl::false_ 249 >::type bound; 250 251 typedef typename mpl::eval_if< 252 is_same<bound, void_> 253 , typename ParameterRequirements::has_default 254 , mpl::apply_wrap2< 255 typename mpl::lambda< 256 typename ParameterRequirements::predicate, lambda_tag 257 >::type 258 , bound 259 , ArgList 260 > 261 >::type type; 262 #else 263 BOOST_STATIC_CONSTANT( 264 bool, value = ( 265 sizeof( 266 aux::to_yesno( 267 ArgList::satisfies((ParameterRequirements*)0, (ArgList*)0) 268 ) 269 ) == sizeof(yes_tag) 270 ) 271 ); 272 273 typedef mpl::bool_<satisfies::value> type; 274 #endif 275 }; 276 277 // Returns mpl::true_ if the requirements of the given ParameterSpec 278 // are satisfied by ArgList. 279 template <class ArgList, class ParameterSpec> 280 struct satisfies_requirements_of 281 : satisfies< 282 ArgList 283 , typename as_parameter_requirements<ParameterSpec>::type 284 > 285 {}; 286 287 // Tags a deduced argument Arg with the keyword tag of Spec using TagFn. 288 // Returns the tagged argument and the mpl::set<> UsedArgs with the 289 // tag of Spec inserted. 290 template <class UsedArgs, class Spec, class Arg, class TagFn> 291 struct tag_deduced 292 { 293 typedef mpl::pair< 294 typename mpl::apply_wrap2<TagFn, typename tag_type<Spec>::type, Arg>::type 295 , typename aux::insert_<UsedArgs, typename tag_type<Spec>::type>::type 296 > type; 297 }; 298 299 template < 300 class Argument 301 , class ArgumentPack 302 , class DeducedArgs 303 , class UsedArgs 304 , class TagFn 305 > 306 struct deduce_tag; 307 308 // Tag type passed to MPL lambda. 309 struct lambda_tag; 310 311 // Helper for deduce_tag<> below. 312 template < 313 class Argument 314 , class ArgumentPack 315 , class DeducedArgs 316 , class UsedArgs 317 , class TagFn 318 > 319 struct deduce_tag0 320 { 321 typedef typename DeducedArgs::spec spec; 322 323 typedef typename mpl::apply_wrap2< 324 typename mpl::lambda< 325 typename spec::predicate, lambda_tag 326 >::type 327 , Argument 328 , ArgumentPack 329 >::type condition; 330 331 // Deduced parameter matches several arguments. 332 333 BOOST_MPL_ASSERT(( 334 mpl::not_<mpl::and_< 335 condition 336 , aux::has_key_<UsedArgs, typename tag_type<spec>::type> 337 > > 338 )); 339 340 typedef typename mpl::eval_if< 341 condition 342 , tag_deduced<UsedArgs, spec, Argument, TagFn> 343 , deduce_tag<Argument, ArgumentPack, typename DeducedArgs::tail, UsedArgs, TagFn> 344 >::type type; 345 }; 346 347 // Tries to deduced a keyword tag for a given Argument. 348 // Returns an mpl::pair<> consisting of the tagged_argument<>, 349 // and an mpl::set<> where the new tag has been inserted. 350 // 351 // Argument: The argument type to be tagged. 352 // 353 // ArgumentPack: The ArgumentPack built so far. 354 // 355 // DeducedArgs: A specialization of deduced_item<> (see below). 356 // A list containing only the deduced ParameterSpecs. 357 // 358 // UsedArgs: An mpl::set<> containing the keyword tags used so far. 359 // 360 // TagFn: A metafunction class used to tag positional or deduced 361 // arguments with a keyword tag. 362 363 template < 364 class Argument 365 , class ArgumentPack 366 , class DeducedArgs 367 , class UsedArgs 368 , class TagFn 369 > 370 struct deduce_tag 371 { 372 typedef typename mpl::eval_if< 373 is_same<DeducedArgs, void_> 374 , mpl::pair<void_, UsedArgs> 375 , deduce_tag0<Argument, ArgumentPack, DeducedArgs, UsedArgs, TagFn> 376 >::type type; 377 }; 378 379 template < 380 class List 381 , class DeducedArgs 382 , class TagFn 383 , class Positional 384 , class UsedArgs 385 , class ArgumentPack 386 , class Error 387 > 388 struct make_arg_list_aux; 389 390 // Inserts Tagged::key_type into the UserArgs set. 391 // Extra indirection to lazily evaluate Tagged::key_type. 392 template <class UsedArgs, class Tagged> 393 struct insert_tagged 394 { 395 typedef typename aux::insert_< 396 UsedArgs, typename Tagged::key_type 397 >::type type; 398 }; 399 400 // Borland needs the insane extra-indirection workaround below 401 // so that it doesn't magically drop the const qualifier from 402 // the argument type. 403 404 template < 405 class List 406 , class DeducedArgs 407 , class TagFn 408 , class Positional 409 , class UsedArgs 410 , class ArgumentPack 411 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 412 , class argument 413 #endif 414 , class Error 415 > 416 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 417 struct make_arg_list00 418 #else 419 struct make_arg_list0 420 #endif 421 { 422 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 423 typedef typename List::arg argument; 424 #endif 425 typedef typename List::spec parameter_spec; 426 typedef typename tag_type<parameter_spec>::type tag_; 427 428 typedef is_named_argument<argument> is_tagged; 429 430 // If this argument is either explicitly tagged or a deduced 431 // parameter, we turn off positional matching. 432 typedef mpl::and_< 433 mpl::not_< 434 mpl::or_<is_deduced<parameter_spec>, is_tagged> 435 > 436 , Positional 437 > positional; 438 439 // If this parameter is explicitly tagged we add it to the 440 // used-parmeters set. We only really need to add parameters 441 // that are deduced, but we would need a way to check if 442 // a given tag corresponds to a deduced parameter spec. 443 typedef typename mpl::eval_if< 444 is_tagged 445 , insert_tagged<UsedArgs, argument> 446 , mpl::identity<UsedArgs> 447 >::type used_args; 448 449 // If this parameter is neither explicitly tagged, nor 450 // positionally matched; deduce the tag from the deduced 451 // parameter specs. 452 typedef typename mpl::eval_if< 453 mpl::or_<is_tagged, positional> 454 , mpl::pair<void_, used_args> 455 , deduce_tag<argument, ArgumentPack, DeducedArgs, used_args, TagFn> 456 >::type deduced_data; 457 458 // If this parameter is explicitly tagged.. 459 typedef typename mpl::eval_if< 460 is_tagged 461 , mpl::identity<argument> // .. just use it 462 , mpl::eval_if< // .. else, if positional matching is turned on.. 463 positional 464 , mpl::apply_wrap2<TagFn, tag_, argument> // .. tag it positionally 465 , mpl::first<deduced_data> // .. else, use the deduced tag 466 > 467 >::type tagged; 468 469 // We build the arg_list incrementally as we go, prepending new 470 // nodes. 471 472 typedef typename mpl::if_< 473 mpl::and_< 474 is_same<Error, void_> 475 , is_same<tagged, void_> 476 > 477 , parameter_::unmatched_argument<argument> 478 , void_ 479 >::type error; 480 481 typedef typename mpl::if_< 482 is_same<tagged, void_> 483 , ArgumentPack 484 , arg_list<tagged, ArgumentPack> 485 >::type argument_pack; 486 487 typedef typename make_arg_list_aux< 488 typename List::tail 489 , DeducedArgs 490 , TagFn 491 , positional 492 , typename deduced_data::second 493 , argument_pack 494 , error 495 >::type type; 496 }; 497 498 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 499 template < 500 class List 501 , class DeducedArgs 502 , class TagFn 503 , class Positional 504 , class UsedArgs 505 , class ArgumentPack 506 , class Error 507 > 508 struct make_arg_list0 509 { 510 typedef typename mpl::eval_if< 511 typename List::is_arg_const 512 , make_arg_list00< 513 List 514 , DeducedArgs 515 , TagFn 516 , Positional 517 , UsedArgs 518 , ArgumentPack 519 , typename List::arg const 520 , Error 521 > 522 , make_arg_list00< 523 List 524 , DeducedArgs 525 , TagFn 526 , Positional 527 , UsedArgs 528 , ArgumentPack 529 , typename List::arg 530 , Error 531 > 532 >::type type; 533 }; 534 #endif 535 536 // Returns an ArgumentPack where the list of arguments has 537 // been tagged with keyword tags. 538 // 539 // List: A specialization of item<> (see below). Contains 540 // both the ordered ParameterSpecs, and the given arguments. 541 // 542 // DeducedArgs: A specialization of deduced_item<> (see below). 543 // A list containing only the deduced ParameterSpecs. 544 // 545 // TagFn: A metafunction class used to tag positional or deduced 546 // arguments with a keyword tag. 547 // 548 // Position: An mpl::bool_<> specialization indicating if positional 549 // matching is to be performed. 550 // 551 // DeducedSet: An mpl::set<> containing the keyword tags used so far. 552 // 553 // ArgumentPack: The ArgumentPack built so far. This is initially an 554 // empty_arg_list and is built incrementally. 555 // 556 557 template < 558 class List 559 , class DeducedArgs 560 , class TagFn 561 , class Positional 562 , class DeducedSet 563 , class ArgumentPack 564 , class Error 565 > 566 struct make_arg_list_aux 567 { 568 typedef typename mpl::eval_if< 569 is_same<List, void_> 570 , mpl::identity<mpl::pair<ArgumentPack, Error> > 571 , make_arg_list0<List, DeducedArgs, TagFn, Positional, DeducedSet, ArgumentPack, Error> 572 >::type type; 573 }; 574 575 // VC6.5 was choking on the default parameters for make_arg_list_aux, so 576 // this just forwards to that adding in the defaults. 577 template < 578 class List 579 , class DeducedArgs 580 , class TagFn 581 , class EmitErrors = mpl::true_ 582 > 583 struct make_arg_list 584 { 585 typedef typename make_arg_list_aux< 586 List, DeducedArgs, TagFn, mpl::true_, aux::set0, empty_arg_list, void_ 587 >::type type; 588 }; 589 590 // A parameter spec item typelist. 591 template <class Spec, class Arg, class Tail = void_> 592 struct item 593 { 594 typedef Spec spec; 595 596 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 597 typedef is_const<Arg> is_arg_const; 598 #endif 599 600 typedef Arg arg; 601 typedef Tail tail; 602 }; 603 604 template <class Spec, class Arg, class Tail> 605 struct make_item 606 { 607 typedef item<Spec, Arg, typename Tail::type> type; 608 }; 609 610 // Creates a item typelist. 611 template <class Spec, class Arg, class Tail> 612 struct make_items 613 { 614 typedef typename mpl::eval_if< 615 is_same<Arg, void_> 616 , mpl::identity<void_> 617 , make_item<Spec, Arg, Tail> 618 >::type type; 619 }; 620 621 // A typelist that stored deduced parameter specs. 622 template <class ParameterSpec, class Tail = void_> 623 struct deduced_item 624 { 625 typedef ParameterSpec spec; 626 typedef Tail tail; 627 }; 628 629 // Evaluate Tail and construct deduced_item list. 630 template <class Spec, class Tail> 631 struct make_deduced_item 632 { 633 typedef deduced_item<Spec, typename Tail::type> type; 634 }; 635 636 template <class Spec, class Tail> 637 struct make_deduced_items 638 { 639 typedef typename mpl::eval_if< 640 is_same<Spec, void_> 641 , mpl::identity<void_> 642 , mpl::eval_if< 643 is_deduced<Spec> 644 , make_deduced_item<Spec, Tail> 645 , Tail 646 > 647 >::type type; 648 }; 649 650 // Generates: 651 // 652 // make< 653 // parameter_spec#0, argument_type#0 654 // , make< 655 // parameter_spec#1, argument_type#1 656 // , ... mpl::identity<aux::empty_arg_list> 657 // ...> 658 // > 659 #define BOOST_PARAMETER_make_arg_list(z, n, names) \ 660 BOOST_PP_SEQ_ELEM(0,names)< \ 661 BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n), \ 662 BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(2,names), n), 663 664 #define BOOST_PARAMETER_right_angle(z, n, text) > 665 666 #define BOOST_PARAMETER_build_arg_list(n, make, parameter_spec, argument_type) \ 667 BOOST_PP_REPEAT( \ 668 n, BOOST_PARAMETER_make_arg_list, (make)(parameter_spec)(argument_type)) \ 669 mpl::identity<void_> \ 670 BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _) 671 672 #define BOOST_PARAMETER_make_deduced_list(z, n, names) \ 673 BOOST_PP_SEQ_ELEM(0,names)< \ 674 BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n), 675 676 #define BOOST_PARAMETER_build_deduced_list(n, make, parameter_spec) \ 677 BOOST_PP_REPEAT( \ 678 n, BOOST_PARAMETER_make_deduced_list, (make)(parameter_spec)) \ 679 mpl::identity<void_> \ 680 BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _) 681 682 struct tag_keyword_arg 683 { 684 template <class K, class T> 685 struct apply 686 : tag<K,T> 687 {}; 688 }; 689 690 struct tag_template_keyword_arg 691 { 692 template <class K, class T> 693 struct apply 694 { 695 typedef template_keyword<K,T> type; 696 }; 697 }; 698 699 } // namespace aux 700 701 #define BOOST_PARAMETER_FORWARD_TYPEDEF(z, i, names) \ 702 typedef BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0,names),i) BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names),i); 703 704 #define BOOST_PARAMETER_FORWARD_TYPEDEFS(n, src, dest) \ 705 BOOST_PP_REPEAT(n, BOOST_PARAMETER_FORWARD_TYPEDEF, (src)(dest)) 706 707 708 #define BOOST_PARAMETER_TEMPLATE_ARGS(z, n, text) class BOOST_PP_CAT(PS, n) = void_ 709 710 template< 711 class PS0 712 , BOOST_PP_ENUM_SHIFTED(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_TEMPLATE_ARGS, _) 713 > 714 struct parameters 715 { 716 #undef BOOST_PARAMETER_TEMPLATE_ARGS 717 718 typedef typename BOOST_PARAMETER_build_deduced_list( 719 BOOST_PARAMETER_MAX_ARITY, aux::make_deduced_items, PS 720 )::type deduced_list; 721 722 // if the elements of NamedList match the criteria of overload 723 // resolution, returns a type which can be constructed from 724 // parameters. Otherwise, this is not a valid metafunction (no nested 725 // ::type). 726 727 728 #if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) 729 // If NamedList satisfies the PS0, PS1, ..., this is a 730 // metafunction returning parameters. Otherwise it 731 // has no nested ::type. 732 template <class ArgumentPackAndError> 733 struct match_base 734 : mpl::if_< 735 // mpl::and_< 736 // aux::satisfies_requirements_of<NamedList,PS0> 737 // , mpl::and_< 738 // aux::satisfies_requirements_of<NamedList,PS1>... 739 // ..., mpl::true_ 740 // ...> > 741 742 # define BOOST_PARAMETER_satisfies(z, n, text) \ 743 mpl::and_< \ 744 aux::satisfies_requirements_of< \ 745 typename mpl::first<ArgumentPackAndError>::type \ 746 , BOOST_PP_CAT(PS, n)> \ 747 , 748 mpl::and_< 749 is_same<typename mpl::second<ArgumentPackAndError>::type, void_> 750 , BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_satisfies, _) 751 mpl::true_ 752 BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_right_angle, _) 753 > 754 755 # undef BOOST_PARAMETER_satisfies 756 757 , mpl::identity<parameters> 758 , void_ 759 > 760 {}; 761 #endif 762 763 // Specializations are to be used as an optional argument to 764 // eliminate overloads via SFINAE 765 template< 766 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 767 // Borland simply can't handle default arguments in member 768 // class templates. People wishing to write portable code can 769 // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments 770 BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A) 771 #else 772 BOOST_PP_ENUM_BINARY_PARAMS( 773 BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT 774 ) 775 #endif 776 > 777 struct match 778 # if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) 779 : match_base< 780 typename aux::make_arg_list< 781 typename BOOST_PARAMETER_build_arg_list( 782 BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A 783 )::type 784 , deduced_list 785 , aux::tag_keyword_arg 786 , mpl::false_ // Don't emit errors when doing SFINAE 787 >::type 788 >::type 789 {}; 790 # else 791 { 792 typedef parameters< 793 BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS) 794 > type; 795 }; 796 # endif 797 798 // Metafunction that returns an ArgumentPack. 799 800 // TODO, bind has to instantiate the error type in the result 801 // of make_arg_list. 802 803 template < 804 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 805 // Borland simply can't handle default arguments in member 806 // class templates. People wishing to write portable code can 807 // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments 808 BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A) 809 #else 810 BOOST_PP_ENUM_BINARY_PARAMS( 811 BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT 812 ) 813 #endif 814 > 815 struct bind 816 { 817 typedef typename aux::make_arg_list< 818 typename BOOST_PARAMETER_build_arg_list( 819 BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A 820 )::type 821 , deduced_list 822 , aux::tag_template_keyword_arg 823 >::type result; 824 825 typedef typename mpl::first<result>::type type; 826 }; 827 BOOST_PARAMETER_FORWARD_TYPEDEFSboost::parameter::parameters828 BOOST_PARAMETER_FORWARD_TYPEDEFS(BOOST_PARAMETER_MAX_ARITY, PS, parameter_spec) 829 830 // 831 // The function call operator is used to build an arg_list that 832 // labels the positional parameters and maintains whatever other 833 // tags may have been specified by the caller. 834 // 835 // !!!NOTE!!! 836 // 837 // The make_arg_list<> produces a reversed arg_list, so 838 // we need to pass the arguments to its constructor 839 // reversed. 840 // 841 aux::empty_arg_list operator()() const 842 { 843 return aux::empty_arg_list(); 844 } 845 846 template<class A0> 847 typename mpl::first< 848 typename aux::make_arg_list< 849 aux::item< 850 PS0,A0 851 > 852 , deduced_list 853 , aux::tag_keyword_arg 854 >::type 855 >::type operator ()boost::parameter::parameters856 operator()(A0& a0) const 857 { 858 typedef typename aux::make_arg_list< 859 aux::item< 860 PS0,A0 861 > 862 , deduced_list 863 , aux::tag_keyword_arg 864 >::type result; 865 866 typedef typename mpl::first<result>::type result_type; 867 typedef typename mpl::second<result>::type error; 868 error(); 869 870 return result_type( 871 a0 872 // , void_(), void_(), void_() ... 873 BOOST_PP_ENUM_TRAILING_PARAMS( 874 BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 1) 875 , aux::void_reference() BOOST_PP_INTERCEPT) 876 ); 877 } 878 879 template<class A0, class A1> 880 typename mpl::first< 881 typename aux::make_arg_list< 882 aux::item< 883 PS0,A0 884 , aux::item< 885 PS1,A1 886 > 887 > 888 , deduced_list 889 , aux::tag_keyword_arg 890 >::type 891 >::type operator ()boost::parameter::parameters892 operator()(A0& a0, A1& a1) const 893 { 894 typedef typename aux::make_arg_list< 895 aux::item< 896 PS0,A0 897 , aux::item< 898 PS1,A1 899 > 900 > 901 , deduced_list 902 , aux::tag_keyword_arg 903 >::type result; 904 905 typedef typename mpl::first<result>::type result_type; 906 typedef typename mpl::second<result>::type error; 907 error(); 908 909 return result_type( 910 a1,a0 911 // , void_(), void_() ... 912 BOOST_PP_ENUM_TRAILING_PARAMS( 913 BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 2) 914 , aux::void_reference() BOOST_PP_INTERCEPT) 915 ); 916 } 917 918 // Higher arities are handled by the preprocessor 919 #define BOOST_PP_ITERATION_PARAMS_1 (3,( \ 920 3,BOOST_PARAMETER_MAX_ARITY,<boost/parameter/aux_/overloads.hpp> \ 921 )) 922 #include BOOST_PP_ITERATE() 923 924 }; 925 926 } // namespace parameter 927 928 } // namespace boost 929 930 #endif // BOOST_PARAMETERS_031014_HPP 931 932