| // Copyright David Abrahams, Daniel Wallin 2003. |
| // Copyright Cromwell D. Enage 2018. |
| // Distributed under the Boost Software License, Version 1.0. |
| // (See accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| |
| #ifndef BOOST_PARAMETER_AUX_PACK_MAKE_ARG_LIST_HPP |
| #define BOOST_PARAMETER_AUX_PACK_MAKE_ARG_LIST_HPP |
| |
| namespace boost { namespace parameter { namespace aux { |
| |
| template < |
| typename List |
| , typename DeducedArgs |
| , typename TagFn |
| , typename IsPositional |
| , typename UsedArgs |
| , typename ArgumentPack |
| , typename Error |
| , typename EmitsErrors |
| > |
| struct make_arg_list_aux; |
| }}} // namespace boost::parameter::aux |
| |
| #include <boost/parameter/aux_/arg_list.hpp> |
| #include <boost/parameter/aux_/void.hpp> |
| #include <boost/parameter/aux_/pack/unmatched_argument.hpp> |
| #include <boost/parameter/aux_/pack/tag_type.hpp> |
| #include <boost/parameter/aux_/pack/is_named_argument.hpp> |
| #include <boost/parameter/aux_/pack/insert_tagged.hpp> |
| #include <boost/parameter/aux_/pack/deduce_tag.hpp> |
| #include <boost/parameter/deduced.hpp> |
| #include <boost/parameter/config.hpp> |
| |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| #include <boost/mp11/integral.hpp> |
| #include <boost/mp11/list.hpp> |
| #include <boost/mp11/utility.hpp> |
| #include <type_traits> |
| #else |
| #include <boost/mpl/bool.hpp> |
| #include <boost/mpl/pair.hpp> |
| #include <boost/mpl/if.hpp> |
| #include <boost/mpl/eval_if.hpp> |
| #include <boost/mpl/apply_wrap.hpp> |
| #include <boost/mpl/identity.hpp> |
| #include <boost/type_traits/is_same.hpp> |
| #include <boost/type_traits/remove_const.hpp> |
| #include <boost/type_traits/remove_reference.hpp> |
| #endif |
| |
| namespace boost { namespace parameter { namespace aux { |
| |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| template <typename ArgumentPack, typename TaggedArg, typename EmitsErrors> |
| struct append_to_make_arg_list |
| { |
| using type = ::boost::mp11::mp_push_front< |
| ArgumentPack |
| , ::boost::parameter::aux::flat_like_arg_tuple< |
| typename TaggedArg::key_type |
| , TaggedArg |
| , EmitsErrors |
| > |
| >; |
| }; |
| #endif |
| |
| // Borland needs the insane extra-indirection workaround below so that |
| // it doesn't magically drop the const qualifier from the argument type. |
| template < |
| typename List |
| , typename DeducedArgs |
| , typename TagFn |
| , typename IsPositional |
| , typename UsedArgs |
| , typename ArgumentPack |
| #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) |
| , typename _argument |
| #endif |
| , typename Error |
| , typename EmitsErrors |
| > |
| #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) |
| class make_arg_list00 |
| #else |
| class make_arg_list0 |
| #endif |
| { |
| #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) |
| typedef typename List::arg _argument; |
| #endif |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| using _arg_type = typename ::std::remove_const< |
| typename ::std::remove_reference<_argument>::type |
| >::type; |
| using _is_tagged = ::boost::parameter::aux |
| ::is_named_argument<_argument>; |
| #else |
| typedef typename ::boost::remove_const< |
| typename ::boost::remove_reference<_argument>::type |
| >::type _arg_type; |
| typedef ::boost::parameter::aux |
| ::is_named_argument<_argument> _is_tagged; |
| #endif |
| typedef typename List::spec _parameter_spec; |
| typedef typename ::boost::parameter::aux |
| ::tag_type<_parameter_spec>::type _tag; |
| |
| // If this argument is either explicitly tagged or a deduced |
| // parameter, then turn off positional matching. |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| using _is_positional = ::boost::mp11::mp_if< |
| IsPositional |
| , ::boost::mp11::mp_if< |
| ::boost::parameter::aux::is_deduced<_parameter_spec> |
| , ::boost::mp11::mp_false |
| , ::boost::mp11::mp_if< |
| _is_tagged |
| , ::boost::mp11::mp_false |
| , ::boost::mp11::mp_true |
| > |
| > |
| , ::boost::mp11::mp_false |
| >; |
| #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) |
| typedef typename ::boost::mpl::eval_if< |
| IsPositional |
| , ::boost::mpl::eval_if< |
| ::boost::parameter::aux::is_deduced<_parameter_spec> |
| , ::boost::mpl::false_ |
| , ::boost::mpl::if_< |
| _is_tagged |
| , ::boost::mpl::false_ |
| , ::boost::mpl::true_ |
| > |
| > |
| , ::boost::mpl::false_ |
| >::type _is_positional; |
| #endif // BOOST_PARAMETER_CAN_USE_MP11 |
| |
| // If this parameter is explicitly tagged, then add it to the |
| // used-parmeters set. We only really need to add parameters |
| // that are deduced, but we would need a way to check if |
| // a given tag corresponds to a deduced parameter spec. |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| using _used_args = typename ::boost::mp11::mp_if< |
| _is_tagged |
| , ::boost::parameter::aux::insert_tagged<UsedArgs,_arg_type> |
| , ::boost::mp11::mp_identity<UsedArgs> |
| >::type; |
| #else |
| typedef typename ::boost::mpl::eval_if< |
| _is_tagged |
| , ::boost::parameter::aux::insert_tagged<UsedArgs,_arg_type> |
| , ::boost::mpl::identity<UsedArgs> |
| >::type _used_args; |
| #endif |
| |
| // If this parameter is neither explicitly tagged nor positionally |
| // matched, then deduce the tag from the deduced parameter specs. |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| using _deduced_data = typename ::boost::mp11::mp_if< |
| ::boost::mp11::mp_if< |
| _is_tagged |
| , ::boost::mp11::mp_true |
| , _is_positional |
| > |
| , ::boost::mp11::mp_identity< |
| ::boost::mp11::mp_list< ::boost::parameter::void_,_used_args> |
| > |
| #else |
| typedef typename ::boost::mpl::eval_if< |
| typename ::boost::mpl::if_< |
| _is_tagged |
| , ::boost::mpl::true_ |
| , _is_positional |
| >::type |
| , ::boost::mpl::pair< ::boost::parameter::void_,_used_args> |
| #endif |
| , ::boost::parameter::aux::deduce_tag< |
| _argument |
| , ArgumentPack |
| , DeducedArgs |
| , _used_args |
| , TagFn |
| , EmitsErrors |
| > |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| >::type; |
| #else |
| >::type _deduced_data; |
| #endif |
| |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| // If this parameter is explicitly tagged ... |
| using _tagged = ::boost::mp11::mp_if< |
| _is_tagged |
| // ... just use it |
| , _arg_type |
| // ... else ... |
| , ::boost::mp11::mp_if< |
| // if positional matching is turned on ... |
| _is_positional |
| // ... tag it positionally |
| , ::boost::mp11::mp_apply_q< |
| TagFn |
| , ::boost::mp11::mp_list<_tag,_argument> |
| > |
| // ... else, use the deduced tag |
| , ::boost::mp11::mp_at_c<_deduced_data,0> |
| > |
| >; |
| #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) |
| // If this parameter is explicitly tagged ... |
| typedef typename ::boost::mpl::eval_if< |
| _is_tagged |
| // ... just use it |
| , ::boost::mpl::identity<_arg_type> |
| // ... else ... |
| , ::boost::mpl::eval_if< |
| // if positional matching is turned on ... |
| _is_positional |
| // ... tag it positionally |
| , ::boost::mpl::apply_wrap2<TagFn,_tag,_argument> |
| // ... else, use the deduced tag |
| , ::boost::mpl::first<_deduced_data> |
| > |
| >::type _tagged; |
| #endif // BOOST_PARAMETER_CAN_USE_MP11 |
| |
| // Build the arg_list incrementally, prepending new nodes. |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| using _error = ::boost::mp11::mp_if< |
| ::boost::mp11::mp_if< |
| ::std::is_same<Error,::boost::parameter::void_> |
| , ::std::is_same<_tagged,::boost::parameter::void_> |
| , ::boost::mp11::mp_false |
| > |
| #else |
| typedef typename ::boost::mpl::if_< |
| typename ::boost::mpl::if_< |
| ::boost::is_same<Error,::boost::parameter::void_> |
| , ::boost::is_same<_tagged,::boost::parameter::void_> |
| , ::boost::mpl::false_ |
| >::type |
| #endif |
| , ::boost::parameter::aux::unmatched_argument<_argument> |
| , ::boost::parameter::void_ |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| >; |
| #else |
| >::type _error; |
| #endif |
| |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| using _argument_pack = typename ::boost::mp11::mp_if< |
| ::std::is_same<_tagged,::boost::parameter::void_> |
| , ::boost::mp11::mp_identity<ArgumentPack> |
| , ::boost::parameter::aux |
| ::append_to_make_arg_list<ArgumentPack,_tagged,EmitsErrors> |
| >::type; |
| #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) |
| typedef typename ::boost::mpl::if_< |
| ::boost::is_same<_tagged,::boost::parameter::void_> |
| , ArgumentPack |
| #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(BOOST_MSVC, < 1800) |
| , ::boost::parameter::aux::arg_list<_tagged,ArgumentPack> |
| #else |
| , ::boost::parameter::aux |
| ::arg_list<_tagged,ArgumentPack,EmitsErrors> |
| #endif |
| >::type _argument_pack; |
| #endif // BOOST_PARAMETER_CAN_USE_MP11 |
| |
| public: |
| typedef typename ::boost::parameter::aux::make_arg_list_aux< |
| typename List::tail |
| , DeducedArgs |
| , TagFn |
| , _is_positional |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| , ::boost::mp11::mp_at_c<_deduced_data,1> |
| #else |
| , typename _deduced_data::second |
| #endif |
| , _argument_pack |
| , _error |
| , EmitsErrors |
| >::type type; |
| }; |
| |
| #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) |
| template < |
| typename List |
| , typename DeducedArgs |
| , typename TagFn |
| , typename IsPositional |
| , typename UsedArgs |
| , typename ArgumentPack |
| , typename Error |
| , typename EmitsErrors |
| > |
| struct make_arg_list0 |
| { |
| typedef typename ::boost::mpl::eval_if< |
| typename List::is_arg_const |
| , ::boost::parameter::aux::make_arg_list00< |
| List |
| , DeducedArgs |
| , TagFn |
| , IsPositional |
| , UsedArgs |
| , ArgumentPack |
| , typename List::arg const |
| , Error |
| , EmitsErrors |
| > |
| , ::boost::parameter::aux::make_arg_list00< |
| List |
| , DeducedArgs |
| , TagFn |
| , IsPositional |
| , UsedArgs |
| , ArgumentPack |
| , typename List::arg |
| , Error |
| , EmitsErrors |
| > |
| >::type type; |
| }; |
| #endif // Borland workarounds needed. |
| |
| // Returns an ArgumentPack where the list of arguments has been tagged |
| // with keyword tags. |
| // |
| // List: A specialization of item<> (see below). Contains both |
| // the ordered ParameterSpecs, and the given arguments. |
| // |
| // DeducedArgs: A specialization of deduced_item<> (see below). |
| // A list containing only the deduced ParameterSpecs. |
| // |
| // TagFn: A metafunction class used to tag positional or deduced |
| // arguments with a keyword tag. |
| // |
| // IsPositional: An mpl::bool_<> specialization indicating if positional |
| // matching is to be performed. |
| // |
| // DeducedSet: An mpl::set<> containing the keyword tags used so far. |
| // |
| // ArgumentPack: The ArgumentPack built so far. This is initially an |
| // empty_arg_list and is built incrementally. |
| template < |
| typename List |
| , typename DeducedArgs |
| , typename TagFn |
| , typename IsPositional |
| , typename DeducedSet |
| , typename ArgumentPack |
| , typename Error |
| , typename EmitsErrors |
| > |
| struct make_arg_list_aux |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| : ::boost::mp11::mp_if< |
| ::std::is_same<List,::boost::parameter::void_> |
| , ::boost::mp11::mp_identity< |
| ::boost::mp11::mp_list<ArgumentPack,Error> |
| > |
| #else |
| : ::boost::mpl::eval_if< |
| ::boost::is_same<List,::boost::parameter::void_> |
| , ::boost::mpl::identity< ::boost::mpl::pair<ArgumentPack,Error> > |
| #endif |
| , ::boost::parameter::aux::make_arg_list0< |
| List |
| , DeducedArgs |
| , TagFn |
| , IsPositional |
| , DeducedSet |
| , ArgumentPack |
| , Error |
| , EmitsErrors |
| > |
| > |
| { |
| }; |
| }}} // namespace boost::parameter::aux |
| |
| #include <boost/parameter/aux_/set.hpp> |
| |
| namespace boost { namespace parameter { namespace aux { |
| |
| // VC6.5 was choking on the default parameters for make_arg_list_aux, |
| // so this just forwards to that adding in the defaults. |
| template < |
| typename List |
| , typename DeducedArgs |
| , typename TagFn |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| , typename EmitsErrors = ::boost::mp11::mp_true |
| #else |
| , typename EmitsErrors = ::boost::mpl::true_ |
| #endif |
| > |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| using make_arg_list = ::boost::parameter::aux::make_arg_list_aux< |
| #else |
| struct make_arg_list |
| : ::boost::parameter::aux::make_arg_list_aux< |
| #endif |
| List |
| , DeducedArgs |
| , TagFn |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| , ::boost::mp11::mp_true |
| #else |
| , ::boost::mpl::true_ |
| #endif |
| , ::boost::parameter::aux::set0 |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| , ::boost::parameter::aux::flat_like_arg_list<> |
| #else |
| , ::boost::parameter::aux::empty_arg_list |
| #endif |
| , ::boost::parameter::void_ |
| , EmitsErrors |
| #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
| >; |
| #else |
| > |
| { |
| }; |
| #endif |
| }}} // namespace boost::parameter::aux |
| |
| #endif // include guard |
| |