annotate DEPENDENCIES/generic/include/boost/parameter/parameters.hpp @ 133:4acb5d8d80b6 tip

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