1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/parameter/parameters.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,931 @@
1.4 +// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
1.5 +// distribution is subject to the Boost Software License, Version 1.0.
1.6 +// (See accompanying file LICENSE_1_0.txt or copy at
1.7 +// http://www.boost.org/LICENSE_1_0.txt)
1.8 +
1.9 +#ifndef BOOST_PARAMETERS_031014_HPP
1.10 +#define BOOST_PARAMETERS_031014_HPP
1.11 +
1.12 +#include <boost/detail/is_xxx.hpp>
1.13 +
1.14 +#include <boost/type_traits/is_const.hpp>
1.15 +
1.16 +#include <boost/mpl/lambda.hpp>
1.17 +#include <boost/mpl/apply.hpp>
1.18 +#include <boost/mpl/always.hpp>
1.19 +#include <boost/mpl/and.hpp>
1.20 +#include <boost/mpl/or.hpp>
1.21 +#include <boost/mpl/if.hpp>
1.22 +#include <boost/mpl/identity.hpp>
1.23 +#include <boost/mpl/not.hpp>
1.24 +#include <boost/mpl/eval_if.hpp>
1.25 +#include <boost/mpl/pair.hpp>
1.26 +
1.27 +#include <boost/type_traits/is_same.hpp>
1.28 +#include <boost/type_traits/remove_reference.hpp>
1.29 +
1.30 +#include <boost/preprocessor/repetition/enum.hpp>
1.31 +#include <boost/preprocessor/repetition/enum_params.hpp>
1.32 +#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
1.33 +#include <boost/preprocessor/arithmetic/sub.hpp>
1.34 +#include <boost/preprocessor/repetition/repeat.hpp>
1.35 +#include <boost/preprocessor/repetition/enum_shifted.hpp>
1.36 +#include <boost/preprocessor/repetition/enum_binary_params.hpp>
1.37 +#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
1.38 +#include <boost/preprocessor/seq/elem.hpp>
1.39 +#include <boost/preprocessor/iteration/iterate.hpp>
1.40 +#include <boost/preprocessor/facilities/intercept.hpp>
1.41 +#include <boost/preprocessor/cat.hpp>
1.42 +
1.43 +#include <boost/parameter/aux_/arg_list.hpp>
1.44 +#include <boost/parameter/aux_/yesno.hpp>
1.45 +#include <boost/parameter/aux_/void.hpp>
1.46 +#include <boost/parameter/aux_/default.hpp>
1.47 +#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
1.48 +#include <boost/parameter/aux_/tagged_argument.hpp>
1.49 +#include <boost/parameter/aux_/tag.hpp>
1.50 +#include <boost/parameter/aux_/template_keyword.hpp>
1.51 +#include <boost/parameter/aux_/set.hpp>
1.52 +#include <boost/parameter/config.hpp>
1.53 +
1.54 +namespace parameter_
1.55 +{
1.56 + template <class T>
1.57 + struct unmatched_argument
1.58 + {
1.59 + BOOST_MPL_ASSERT((boost::is_same<T,void>));
1.60 + typedef int type;
1.61 + };
1.62 +} // namespace parameter_
1.63 +
1.64 +namespace boost {
1.65 +
1.66 +template<class T> class reference_wrapper;
1.67 +
1.68 +namespace parameter {
1.69 +
1.70 +namespace aux { struct use_default {}; }
1.71 +
1.72 +// These templates can be used to describe the treatment of particular
1.73 +// named parameters for the purposes of overload elimination with
1.74 +// SFINAE, by placing specializations in the parameters<...> list. In
1.75 +// order for a treated function to participate in overload resolution:
1.76 +//
1.77 +// - all keyword tags wrapped in required<...> must have a matching
1.78 +// actual argument
1.79 +//
1.80 +// - The actual argument type matched by every keyword tag
1.81 +// associated with a predicate must satisfy that predicate
1.82 +//
1.83 +// If a keyword k is specified without an optional<...> or
1.84 +// required<...>, wrapper, it is treated as though optional<k> were
1.85 +// specified.
1.86 +//
1.87 +// If a keyword k is specified with deduced<...>, that keyword
1.88 +// will be automatically deduced from the argument list.
1.89 +//
1.90 +template <class Tag, class Predicate = aux::use_default>
1.91 +struct required
1.92 +{
1.93 + typedef Tag key_type;
1.94 + typedef Predicate predicate;
1.95 +};
1.96 +
1.97 +template <class Tag, class Predicate = aux::use_default>
1.98 +struct optional
1.99 +{
1.100 + typedef Tag key_type;
1.101 + typedef Predicate predicate;
1.102 +};
1.103 +
1.104 +template <class Tag>
1.105 +struct deduced
1.106 +{
1.107 + typedef Tag key_type;
1.108 +};
1.109 +
1.110 +namespace aux
1.111 +{
1.112 + // Defines metafunctions, is_required and is_optional, that
1.113 + // identify required<...>, optional<...> and deduced<...> specializations.
1.114 + BOOST_DETAIL_IS_XXX_DEF(required, required, 2)
1.115 + BOOST_DETAIL_IS_XXX_DEF(optional, optional, 2)
1.116 + BOOST_DETAIL_IS_XXX_DEF(deduced_aux, deduced, 1)
1.117 +
1.118 + template <class S>
1.119 + struct is_deduced0
1.120 + : is_deduced_aux<
1.121 + typename S::key_type
1.122 + >::type
1.123 + {};
1.124 +
1.125 + template <class S>
1.126 + struct is_deduced
1.127 + : mpl::eval_if<
1.128 + mpl::or_<
1.129 + is_optional<S>, is_required<S>
1.130 + >
1.131 + , is_deduced0<S>
1.132 + , mpl::false_
1.133 + >::type
1.134 + {};
1.135 +
1.136 + //
1.137 + // key_type, has_default, and predicate --
1.138 + //
1.139 + // These metafunctions accept a ParameterSpec and extract the
1.140 + // keyword tag, whether or not a default is supplied for the
1.141 + // parameter, and the predicate that the corresponding actual
1.142 + // argument type is required match.
1.143 + //
1.144 + // a ParameterSpec is a specialization of either keyword<...>,
1.145 + // required<...>, optional<...>
1.146 + //
1.147 +
1.148 + // helper for key_type<...>, below.
1.149 + template <class T>
1.150 + struct get_tag_type0
1.151 + {
1.152 + typedef typename T::key_type type;
1.153 + };
1.154 +
1.155 + template <class T>
1.156 + struct get_tag_type
1.157 + : mpl::eval_if<
1.158 + is_deduced_aux<typename T::key_type>
1.159 + , get_tag_type0<typename T::key_type>
1.160 + , mpl::identity<typename T::key_type>
1.161 + >
1.162 + {};
1.163 +
1.164 + template <class T>
1.165 + struct tag_type
1.166 + : mpl::eval_if<
1.167 + mpl::or_<
1.168 + is_optional<T>
1.169 + , is_required<T>
1.170 + >
1.171 + , get_tag_type<T>
1.172 + , mpl::identity<T>
1.173 + >
1.174 + {};
1.175 +
1.176 + template <class T>
1.177 + struct has_default
1.178 + : mpl::not_<is_required<T> >
1.179 + {};
1.180 +
1.181 + // helper for get_predicate<...>, below
1.182 + template <class T>
1.183 + struct get_predicate_or_default
1.184 + {
1.185 + typedef T type;
1.186 + };
1.187 +
1.188 + template <>
1.189 + struct get_predicate_or_default<use_default>
1.190 + {
1.191 + typedef mpl::always<mpl::true_> type;
1.192 + };
1.193 +
1.194 + // helper for predicate<...>, below
1.195 + template <class T>
1.196 + struct get_predicate
1.197 + {
1.198 + typedef typename
1.199 + get_predicate_or_default<typename T::predicate>::type
1.200 + type;
1.201 + };
1.202 +
1.203 + template <class T>
1.204 + struct predicate
1.205 + : mpl::eval_if<
1.206 + mpl::or_<
1.207 + is_optional<T>
1.208 + , is_required<T>
1.209 + >
1.210 + , get_predicate<T>
1.211 + , mpl::identity<mpl::always<mpl::true_> >
1.212 + >
1.213 + {
1.214 + };
1.215 +
1.216 +
1.217 + // Converts a ParameterSpec into a specialization of
1.218 + // parameter_requirements. We need to do this in order to get the
1.219 + // tag_type into the type in a way that can be conveniently matched
1.220 + // by a satisfies(...) member function in arg_list.
1.221 + template <class ParameterSpec>
1.222 + struct as_parameter_requirements
1.223 + {
1.224 + typedef parameter_requirements<
1.225 + typename tag_type<ParameterSpec>::type
1.226 + , typename predicate<ParameterSpec>::type
1.227 + , typename has_default<ParameterSpec>::type
1.228 + > type;
1.229 + };
1.230 +
1.231 + template <class T>
1.232 + struct is_named_argument
1.233 + : mpl::or_<
1.234 + is_template_keyword<T>
1.235 + , is_tagged_argument<T>
1.236 + >
1.237 + {};
1.238 +
1.239 + // Returns mpl::true_ iff the given ParameterRequirements are
1.240 + // satisfied by ArgList.
1.241 + template <class ArgList, class ParameterRequirements>
1.242 + struct satisfies
1.243 + {
1.244 +#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
1.245 + // VC7.1 can't handle the sizeof() implementation below,
1.246 + // so we use this instead.
1.247 + typedef typename mpl::apply_wrap3<
1.248 + typename ArgList::binding
1.249 + , typename ParameterRequirements::keyword
1.250 + , void_
1.251 + , mpl::false_
1.252 + >::type bound;
1.253 +
1.254 + typedef typename mpl::eval_if<
1.255 + is_same<bound, void_>
1.256 + , typename ParameterRequirements::has_default
1.257 + , mpl::apply_wrap2<
1.258 + typename mpl::lambda<
1.259 + typename ParameterRequirements::predicate, lambda_tag
1.260 + >::type
1.261 + , bound
1.262 + , ArgList
1.263 + >
1.264 + >::type type;
1.265 +#else
1.266 + BOOST_STATIC_CONSTANT(
1.267 + bool, value = (
1.268 + sizeof(
1.269 + aux::to_yesno(
1.270 + ArgList::satisfies((ParameterRequirements*)0, (ArgList*)0)
1.271 + )
1.272 + ) == sizeof(yes_tag)
1.273 + )
1.274 + );
1.275 +
1.276 + typedef mpl::bool_<satisfies::value> type;
1.277 +#endif
1.278 + };
1.279 +
1.280 + // Returns mpl::true_ if the requirements of the given ParameterSpec
1.281 + // are satisfied by ArgList.
1.282 + template <class ArgList, class ParameterSpec>
1.283 + struct satisfies_requirements_of
1.284 + : satisfies<
1.285 + ArgList
1.286 + , typename as_parameter_requirements<ParameterSpec>::type
1.287 + >
1.288 + {};
1.289 +
1.290 + // Tags a deduced argument Arg with the keyword tag of Spec using TagFn.
1.291 + // Returns the tagged argument and the mpl::set<> UsedArgs with the
1.292 + // tag of Spec inserted.
1.293 + template <class UsedArgs, class Spec, class Arg, class TagFn>
1.294 + struct tag_deduced
1.295 + {
1.296 + typedef mpl::pair<
1.297 + typename mpl::apply_wrap2<TagFn, typename tag_type<Spec>::type, Arg>::type
1.298 + , typename aux::insert_<UsedArgs, typename tag_type<Spec>::type>::type
1.299 + > type;
1.300 + };
1.301 +
1.302 + template <
1.303 + class Argument
1.304 + , class ArgumentPack
1.305 + , class DeducedArgs
1.306 + , class UsedArgs
1.307 + , class TagFn
1.308 + >
1.309 + struct deduce_tag;
1.310 +
1.311 + // Tag type passed to MPL lambda.
1.312 + struct lambda_tag;
1.313 +
1.314 + // Helper for deduce_tag<> below.
1.315 + template <
1.316 + class Argument
1.317 + , class ArgumentPack
1.318 + , class DeducedArgs
1.319 + , class UsedArgs
1.320 + , class TagFn
1.321 + >
1.322 + struct deduce_tag0
1.323 + {
1.324 + typedef typename DeducedArgs::spec spec;
1.325 +
1.326 + typedef typename mpl::apply_wrap2<
1.327 + typename mpl::lambda<
1.328 + typename spec::predicate, lambda_tag
1.329 + >::type
1.330 + , Argument
1.331 + , ArgumentPack
1.332 + >::type condition;
1.333 +
1.334 + // Deduced parameter matches several arguments.
1.335 +
1.336 + BOOST_MPL_ASSERT((
1.337 + mpl::not_<mpl::and_<
1.338 + condition
1.339 + , aux::has_key_<UsedArgs, typename tag_type<spec>::type>
1.340 + > >
1.341 + ));
1.342 +
1.343 + typedef typename mpl::eval_if<
1.344 + condition
1.345 + , tag_deduced<UsedArgs, spec, Argument, TagFn>
1.346 + , deduce_tag<Argument, ArgumentPack, typename DeducedArgs::tail, UsedArgs, TagFn>
1.347 + >::type type;
1.348 + };
1.349 +
1.350 + // Tries to deduced a keyword tag for a given Argument.
1.351 + // Returns an mpl::pair<> consisting of the tagged_argument<>,
1.352 + // and an mpl::set<> where the new tag has been inserted.
1.353 + //
1.354 + // Argument: The argument type to be tagged.
1.355 + //
1.356 + // ArgumentPack: The ArgumentPack built so far.
1.357 + //
1.358 + // DeducedArgs: A specialization of deduced_item<> (see below).
1.359 + // A list containing only the deduced ParameterSpecs.
1.360 + //
1.361 + // UsedArgs: An mpl::set<> containing the keyword tags used so far.
1.362 + //
1.363 + // TagFn: A metafunction class used to tag positional or deduced
1.364 + // arguments with a keyword tag.
1.365 +
1.366 + template <
1.367 + class Argument
1.368 + , class ArgumentPack
1.369 + , class DeducedArgs
1.370 + , class UsedArgs
1.371 + , class TagFn
1.372 + >
1.373 + struct deduce_tag
1.374 + {
1.375 + typedef typename mpl::eval_if<
1.376 + is_same<DeducedArgs, void_>
1.377 + , mpl::pair<void_, UsedArgs>
1.378 + , deduce_tag0<Argument, ArgumentPack, DeducedArgs, UsedArgs, TagFn>
1.379 + >::type type;
1.380 + };
1.381 +
1.382 + template <
1.383 + class List
1.384 + , class DeducedArgs
1.385 + , class TagFn
1.386 + , class Positional
1.387 + , class UsedArgs
1.388 + , class ArgumentPack
1.389 + , class Error
1.390 + >
1.391 + struct make_arg_list_aux;
1.392 +
1.393 + // Inserts Tagged::key_type into the UserArgs set.
1.394 + // Extra indirection to lazily evaluate Tagged::key_type.
1.395 + template <class UsedArgs, class Tagged>
1.396 + struct insert_tagged
1.397 + {
1.398 + typedef typename aux::insert_<
1.399 + UsedArgs, typename Tagged::key_type
1.400 + >::type type;
1.401 + };
1.402 +
1.403 + // Borland needs the insane extra-indirection workaround below
1.404 + // so that it doesn't magically drop the const qualifier from
1.405 + // the argument type.
1.406 +
1.407 + template <
1.408 + class List
1.409 + , class DeducedArgs
1.410 + , class TagFn
1.411 + , class Positional
1.412 + , class UsedArgs
1.413 + , class ArgumentPack
1.414 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
1.415 + , class argument
1.416 +#endif
1.417 + , class Error
1.418 + >
1.419 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
1.420 + struct make_arg_list00
1.421 +#else
1.422 + struct make_arg_list0
1.423 +#endif
1.424 + {
1.425 +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
1.426 + typedef typename List::arg argument;
1.427 +#endif
1.428 + typedef typename List::spec parameter_spec;
1.429 + typedef typename tag_type<parameter_spec>::type tag_;
1.430 +
1.431 + typedef is_named_argument<argument> is_tagged;
1.432 +
1.433 + // If this argument is either explicitly tagged or a deduced
1.434 + // parameter, we turn off positional matching.
1.435 + typedef mpl::and_<
1.436 + mpl::not_<
1.437 + mpl::or_<is_deduced<parameter_spec>, is_tagged>
1.438 + >
1.439 + , Positional
1.440 + > positional;
1.441 +
1.442 + // If this parameter is explicitly tagged we add it to the
1.443 + // used-parmeters set. We only really need to add parameters
1.444 + // that are deduced, but we would need a way to check if
1.445 + // a given tag corresponds to a deduced parameter spec.
1.446 + typedef typename mpl::eval_if<
1.447 + is_tagged
1.448 + , insert_tagged<UsedArgs, argument>
1.449 + , mpl::identity<UsedArgs>
1.450 + >::type used_args;
1.451 +
1.452 + // If this parameter is neither explicitly tagged, nor
1.453 + // positionally matched; deduce the tag from the deduced
1.454 + // parameter specs.
1.455 + typedef typename mpl::eval_if<
1.456 + mpl::or_<is_tagged, positional>
1.457 + , mpl::pair<void_, used_args>
1.458 + , deduce_tag<argument, ArgumentPack, DeducedArgs, used_args, TagFn>
1.459 + >::type deduced_data;
1.460 +
1.461 + // If this parameter is explicitly tagged..
1.462 + typedef typename mpl::eval_if<
1.463 + is_tagged
1.464 + , mpl::identity<argument> // .. just use it
1.465 + , mpl::eval_if< // .. else, if positional matching is turned on..
1.466 + positional
1.467 + , mpl::apply_wrap2<TagFn, tag_, argument> // .. tag it positionally
1.468 + , mpl::first<deduced_data> // .. else, use the deduced tag
1.469 + >
1.470 + >::type tagged;
1.471 +
1.472 + // We build the arg_list incrementally as we go, prepending new
1.473 + // nodes.
1.474 +
1.475 + typedef typename mpl::if_<
1.476 + mpl::and_<
1.477 + is_same<Error, void_>
1.478 + , is_same<tagged, void_>
1.479 + >
1.480 + , parameter_::unmatched_argument<argument>
1.481 + , void_
1.482 + >::type error;
1.483 +
1.484 + typedef typename mpl::if_<
1.485 + is_same<tagged, void_>
1.486 + , ArgumentPack
1.487 + , arg_list<tagged, ArgumentPack>
1.488 + >::type argument_pack;
1.489 +
1.490 + typedef typename make_arg_list_aux<
1.491 + typename List::tail
1.492 + , DeducedArgs
1.493 + , TagFn
1.494 + , positional
1.495 + , typename deduced_data::second
1.496 + , argument_pack
1.497 + , error
1.498 + >::type type;
1.499 + };
1.500 +
1.501 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
1.502 + template <
1.503 + class List
1.504 + , class DeducedArgs
1.505 + , class TagFn
1.506 + , class Positional
1.507 + , class UsedArgs
1.508 + , class ArgumentPack
1.509 + , class Error
1.510 + >
1.511 + struct make_arg_list0
1.512 + {
1.513 + typedef typename mpl::eval_if<
1.514 + typename List::is_arg_const
1.515 + , make_arg_list00<
1.516 + List
1.517 + , DeducedArgs
1.518 + , TagFn
1.519 + , Positional
1.520 + , UsedArgs
1.521 + , ArgumentPack
1.522 + , typename List::arg const
1.523 + , Error
1.524 + >
1.525 + , make_arg_list00<
1.526 + List
1.527 + , DeducedArgs
1.528 + , TagFn
1.529 + , Positional
1.530 + , UsedArgs
1.531 + , ArgumentPack
1.532 + , typename List::arg
1.533 + , Error
1.534 + >
1.535 + >::type type;
1.536 + };
1.537 +#endif
1.538 +
1.539 + // Returns an ArgumentPack where the list of arguments has
1.540 + // been tagged with keyword tags.
1.541 + //
1.542 + // List: A specialization of item<> (see below). Contains
1.543 + // both the ordered ParameterSpecs, and the given arguments.
1.544 + //
1.545 + // DeducedArgs: A specialization of deduced_item<> (see below).
1.546 + // A list containing only the deduced ParameterSpecs.
1.547 + //
1.548 + // TagFn: A metafunction class used to tag positional or deduced
1.549 + // arguments with a keyword tag.
1.550 + //
1.551 + // Position: An mpl::bool_<> specialization indicating if positional
1.552 + // matching is to be performed.
1.553 + //
1.554 + // DeducedSet: An mpl::set<> containing the keyword tags used so far.
1.555 + //
1.556 + // ArgumentPack: The ArgumentPack built so far. This is initially an
1.557 + // empty_arg_list and is built incrementally.
1.558 + //
1.559 +
1.560 + template <
1.561 + class List
1.562 + , class DeducedArgs
1.563 + , class TagFn
1.564 + , class Positional
1.565 + , class DeducedSet
1.566 + , class ArgumentPack
1.567 + , class Error
1.568 + >
1.569 + struct make_arg_list_aux
1.570 + {
1.571 + typedef typename mpl::eval_if<
1.572 + is_same<List, void_>
1.573 + , mpl::identity<mpl::pair<ArgumentPack, Error> >
1.574 + , make_arg_list0<List, DeducedArgs, TagFn, Positional, DeducedSet, ArgumentPack, Error>
1.575 + >::type type;
1.576 + };
1.577 +
1.578 + // VC6.5 was choking on the default parameters for make_arg_list_aux, so
1.579 + // this just forwards to that adding in the defaults.
1.580 + template <
1.581 + class List
1.582 + , class DeducedArgs
1.583 + , class TagFn
1.584 + , class EmitErrors = mpl::true_
1.585 + >
1.586 + struct make_arg_list
1.587 + {
1.588 + typedef typename make_arg_list_aux<
1.589 + List, DeducedArgs, TagFn, mpl::true_, aux::set0, empty_arg_list, void_
1.590 + >::type type;
1.591 + };
1.592 +
1.593 + // A parameter spec item typelist.
1.594 + template <class Spec, class Arg, class Tail = void_>
1.595 + struct item
1.596 + {
1.597 + typedef Spec spec;
1.598 +
1.599 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
1.600 + typedef is_const<Arg> is_arg_const;
1.601 +#endif
1.602 +
1.603 + typedef Arg arg;
1.604 + typedef Tail tail;
1.605 + };
1.606 +
1.607 + template <class Spec, class Arg, class Tail>
1.608 + struct make_item
1.609 + {
1.610 + typedef item<Spec, Arg, typename Tail::type> type;
1.611 + };
1.612 +
1.613 + // Creates a item typelist.
1.614 + template <class Spec, class Arg, class Tail>
1.615 + struct make_items
1.616 + {
1.617 + typedef typename mpl::eval_if<
1.618 + is_same<Arg, void_>
1.619 + , mpl::identity<void_>
1.620 + , make_item<Spec, Arg, Tail>
1.621 + >::type type;
1.622 + };
1.623 +
1.624 + // A typelist that stored deduced parameter specs.
1.625 + template <class ParameterSpec, class Tail = void_>
1.626 + struct deduced_item
1.627 + {
1.628 + typedef ParameterSpec spec;
1.629 + typedef Tail tail;
1.630 + };
1.631 +
1.632 + // Evaluate Tail and construct deduced_item list.
1.633 + template <class Spec, class Tail>
1.634 + struct make_deduced_item
1.635 + {
1.636 + typedef deduced_item<Spec, typename Tail::type> type;
1.637 + };
1.638 +
1.639 + template <class Spec, class Tail>
1.640 + struct make_deduced_items
1.641 + {
1.642 + typedef typename mpl::eval_if<
1.643 + is_same<Spec, void_>
1.644 + , mpl::identity<void_>
1.645 + , mpl::eval_if<
1.646 + is_deduced<Spec>
1.647 + , make_deduced_item<Spec, Tail>
1.648 + , Tail
1.649 + >
1.650 + >::type type;
1.651 + };
1.652 +
1.653 + // Generates:
1.654 + //
1.655 + // make<
1.656 + // parameter_spec#0, argument_type#0
1.657 + // , make<
1.658 + // parameter_spec#1, argument_type#1
1.659 + // , ... mpl::identity<aux::empty_arg_list>
1.660 + // ...>
1.661 + // >
1.662 +#define BOOST_PARAMETER_make_arg_list(z, n, names) \
1.663 + BOOST_PP_SEQ_ELEM(0,names)< \
1.664 + BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n), \
1.665 + BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(2,names), n),
1.666 +
1.667 +#define BOOST_PARAMETER_right_angle(z, n, text) >
1.668 +
1.669 +#define BOOST_PARAMETER_build_arg_list(n, make, parameter_spec, argument_type) \
1.670 + BOOST_PP_REPEAT( \
1.671 + n, BOOST_PARAMETER_make_arg_list, (make)(parameter_spec)(argument_type)) \
1.672 + mpl::identity<void_> \
1.673 + BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
1.674 +
1.675 +#define BOOST_PARAMETER_make_deduced_list(z, n, names) \
1.676 + BOOST_PP_SEQ_ELEM(0,names)< \
1.677 + BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n),
1.678 +
1.679 +#define BOOST_PARAMETER_build_deduced_list(n, make, parameter_spec) \
1.680 + BOOST_PP_REPEAT( \
1.681 + n, BOOST_PARAMETER_make_deduced_list, (make)(parameter_spec)) \
1.682 + mpl::identity<void_> \
1.683 + BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
1.684 +
1.685 + struct tag_keyword_arg
1.686 + {
1.687 + template <class K, class T>
1.688 + struct apply
1.689 + : tag<K,T>
1.690 + {};
1.691 + };
1.692 +
1.693 + struct tag_template_keyword_arg
1.694 + {
1.695 + template <class K, class T>
1.696 + struct apply
1.697 + {
1.698 + typedef template_keyword<K,T> type;
1.699 + };
1.700 + };
1.701 +
1.702 +} // namespace aux
1.703 +
1.704 +#define BOOST_PARAMETER_FORWARD_TYPEDEF(z, i, names) \
1.705 + typedef BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0,names),i) BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names),i);
1.706 +
1.707 +#define BOOST_PARAMETER_FORWARD_TYPEDEFS(n, src, dest) \
1.708 + BOOST_PP_REPEAT(n, BOOST_PARAMETER_FORWARD_TYPEDEF, (src)(dest))
1.709 +
1.710 +
1.711 +#define BOOST_PARAMETER_TEMPLATE_ARGS(z, n, text) class BOOST_PP_CAT(PS, n) = void_
1.712 +
1.713 +template<
1.714 + class PS0
1.715 + , BOOST_PP_ENUM_SHIFTED(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_TEMPLATE_ARGS, _)
1.716 +>
1.717 +struct parameters
1.718 +{
1.719 +#undef BOOST_PARAMETER_TEMPLATE_ARGS
1.720 +
1.721 + typedef typename BOOST_PARAMETER_build_deduced_list(
1.722 + BOOST_PARAMETER_MAX_ARITY, aux::make_deduced_items, PS
1.723 + )::type deduced_list;
1.724 +
1.725 + // if the elements of NamedList match the criteria of overload
1.726 + // resolution, returns a type which can be constructed from
1.727 + // parameters. Otherwise, this is not a valid metafunction (no nested
1.728 + // ::type).
1.729 +
1.730 +
1.731 +#ifndef BOOST_NO_SFINAE
1.732 + // If NamedList satisfies the PS0, PS1, ..., this is a
1.733 + // metafunction returning parameters. Otherwise it
1.734 + // has no nested ::type.
1.735 + template <class ArgumentPackAndError>
1.736 + struct match_base
1.737 + : mpl::if_<
1.738 + // mpl::and_<
1.739 + // aux::satisfies_requirements_of<NamedList,PS0>
1.740 + // , mpl::and_<
1.741 + // aux::satisfies_requirements_of<NamedList,PS1>...
1.742 + // ..., mpl::true_
1.743 + // ...> >
1.744 +
1.745 +# define BOOST_PARAMETER_satisfies(z, n, text) \
1.746 + mpl::and_< \
1.747 + aux::satisfies_requirements_of< \
1.748 + typename mpl::first<ArgumentPackAndError>::type \
1.749 + , BOOST_PP_CAT(PS, n)> \
1.750 + ,
1.751 + mpl::and_<
1.752 + is_same<typename mpl::second<ArgumentPackAndError>::type, void_>
1.753 + , BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_satisfies, _)
1.754 + mpl::true_
1.755 + BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_right_angle, _)
1.756 + >
1.757 +
1.758 +# undef BOOST_PARAMETER_satisfies
1.759 +
1.760 + , mpl::identity<parameters>
1.761 + , void_
1.762 + >
1.763 + {};
1.764 +#endif
1.765 +
1.766 + // Specializations are to be used as an optional argument to
1.767 + // eliminate overloads via SFINAE
1.768 + template<
1.769 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
1.770 + // Borland simply can't handle default arguments in member
1.771 + // class templates. People wishing to write portable code can
1.772 + // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments
1.773 + BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
1.774 +#else
1.775 + BOOST_PP_ENUM_BINARY_PARAMS(
1.776 + BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT
1.777 + )
1.778 +#endif
1.779 + >
1.780 + struct match
1.781 +# ifndef BOOST_NO_SFINAE
1.782 + : match_base<
1.783 + typename aux::make_arg_list<
1.784 + typename BOOST_PARAMETER_build_arg_list(
1.785 + BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A
1.786 + )::type
1.787 + , deduced_list
1.788 + , aux::tag_keyword_arg
1.789 + , mpl::false_ // Don't emit errors when doing SFINAE
1.790 + >::type
1.791 + >::type
1.792 + {};
1.793 +# else
1.794 + {
1.795 + typedef parameters<
1.796 + BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS)
1.797 + > type;
1.798 + };
1.799 +# endif
1.800 +
1.801 + // Metafunction that returns an ArgumentPack.
1.802 +
1.803 + // TODO, bind has to instantiate the error type in the result
1.804 + // of make_arg_list.
1.805 +
1.806 + template <
1.807 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
1.808 + // Borland simply can't handle default arguments in member
1.809 + // class templates. People wishing to write portable code can
1.810 + // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments
1.811 + BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
1.812 +#else
1.813 + BOOST_PP_ENUM_BINARY_PARAMS(
1.814 + BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT
1.815 + )
1.816 +#endif
1.817 + >
1.818 + struct bind
1.819 + {
1.820 + typedef typename aux::make_arg_list<
1.821 + typename BOOST_PARAMETER_build_arg_list(
1.822 + BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A
1.823 + )::type
1.824 + , deduced_list
1.825 + , aux::tag_template_keyword_arg
1.826 + >::type result;
1.827 +
1.828 + typedef typename mpl::first<result>::type type;
1.829 + };
1.830 +
1.831 + BOOST_PARAMETER_FORWARD_TYPEDEFS(BOOST_PARAMETER_MAX_ARITY, PS, parameter_spec)
1.832 +
1.833 + //
1.834 + // The function call operator is used to build an arg_list that
1.835 + // labels the positional parameters and maintains whatever other
1.836 + // tags may have been specified by the caller.
1.837 + //
1.838 + // !!!NOTE!!!
1.839 + //
1.840 + // The make_arg_list<> produces a reversed arg_list, so
1.841 + // we need to pass the arguments to it's constructor
1.842 + // reversed.
1.843 + //
1.844 + aux::empty_arg_list operator()() const
1.845 + {
1.846 + return aux::empty_arg_list();
1.847 + }
1.848 +
1.849 + template<class A0>
1.850 + typename mpl::first<
1.851 + typename aux::make_arg_list<
1.852 + aux::item<
1.853 + PS0,A0
1.854 + >
1.855 + , deduced_list
1.856 + , aux::tag_keyword_arg
1.857 + >::type
1.858 + >::type
1.859 + operator()(A0& a0) const
1.860 + {
1.861 + typedef typename aux::make_arg_list<
1.862 + aux::item<
1.863 + PS0,A0
1.864 + >
1.865 + , deduced_list
1.866 + , aux::tag_keyword_arg
1.867 + >::type result;
1.868 +
1.869 + typedef typename mpl::first<result>::type result_type;
1.870 + typedef typename mpl::second<result>::type error;
1.871 + error();
1.872 +
1.873 + return result_type(
1.874 + a0
1.875 + // , void_(), void_(), void_() ...
1.876 + BOOST_PP_ENUM_TRAILING_PARAMS(
1.877 + BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 1)
1.878 + , aux::void_reference() BOOST_PP_INTERCEPT)
1.879 + );
1.880 + }
1.881 +
1.882 + template<class A0, class A1>
1.883 + typename mpl::first<
1.884 + typename aux::make_arg_list<
1.885 + aux::item<
1.886 + PS0,A0
1.887 + , aux::item<
1.888 + PS1,A1
1.889 + >
1.890 + >
1.891 + , deduced_list
1.892 + , aux::tag_keyword_arg
1.893 + >::type
1.894 + >::type
1.895 + operator()(A0& a0, A1& a1) const
1.896 + {
1.897 + typedef typename aux::make_arg_list<
1.898 + aux::item<
1.899 + PS0,A0
1.900 + , aux::item<
1.901 + PS1,A1
1.902 + >
1.903 + >
1.904 + , deduced_list
1.905 + , aux::tag_keyword_arg
1.906 + >::type result;
1.907 +
1.908 + typedef typename mpl::first<result>::type result_type;
1.909 + typedef typename mpl::second<result>::type error;
1.910 + error();
1.911 +
1.912 + return result_type(
1.913 + a1,a0
1.914 + // , void_(), void_() ...
1.915 + BOOST_PP_ENUM_TRAILING_PARAMS(
1.916 + BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 2)
1.917 + , aux::void_reference() BOOST_PP_INTERCEPT)
1.918 + );
1.919 + }
1.920 +
1.921 + // Higher arities are handled by the preprocessor
1.922 +#define BOOST_PP_ITERATION_PARAMS_1 (3,( \
1.923 + 3,BOOST_PARAMETER_MAX_ARITY,<boost/parameter/aux_/overloads.hpp> \
1.924 + ))
1.925 +#include BOOST_PP_ITERATE()
1.926 +
1.927 +};
1.928 +
1.929 +} // namespace parameter
1.930 +
1.931 +} // namespace boost
1.932 +
1.933 +#endif // BOOST_PARAMETERS_031014_HPP
1.934 +