// Copyright David Abrahams, Daniel Wallin 2003. // Copyright Cromwell D. Enage 2017. // 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_PARAMETERS_031014_HPP #define BOOST_PARAMETERS_031014_HPP #include #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) namespace boost { namespace parameter { namespace aux { // The make_arg_list<> metafunction produces a reversed arg_list, // so pass the arguments to the arg_list constructor reversed in turn. template struct arg_list_factory; }}} // namespace boost::parameter::aux #include #include #if defined(BOOST_PARAMETER_CAN_USE_MP11) #include #include #else #include #include #endif namespace boost { namespace parameter { namespace aux { // TODO: Reduce template code bloat. -- Cromwell D. Enage template struct arg_list_factory { template static inline BOOST_CONSTEXPR ArgList reverse(ReversedArgs&&... reversed_args) { return ArgList( #if defined(BOOST_PARAMETER_CAN_USE_MP11) ::boost::mp11::mp_if< ::std::is_same< #else typename ::boost::mpl::if_< ::boost::is_same< #endif typename ArgList::tagged_arg::value_type , ::boost::parameter::void_ > , ::boost::parameter::aux::value_type_is_void , ::boost::parameter::aux::value_type_is_not_void #if defined(BOOST_PARAMETER_CAN_USE_MP11) >() #else >::type() #endif , ::std::forward(reversed_args)... ); } }; template struct arg_list_factory { template static inline BOOST_CONSTEXPR ArgList reverse(A0&& a0, Args&&... args, ReversedArgs&&... reversed_args) { return ::boost::parameter::aux ::arg_list_factory::reverse( ::std::forward(args)... , ::std::forward(a0) , ::std::forward(reversed_args)... ); } }; }}} // namespace boost::parameter::aux #include #include #include #include #include #if defined(BOOST_PARAMETER_CAN_USE_MP11) #include #include #else #include #include #include #endif #if !defined(BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE) #if defined(BOOST_PARAMETER_CAN_USE_MP11) //#include #define BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE ::boost::mp11::mp_list #else #include // Newer versions of MSVC fail on the evaluate_category and // preprocessor_eval_category test programs when parameters uses // boost::fusion::list. // -- Cromwell D. Enage #if defined(BOOST_FUSION_HAS_VARIADIC_LIST) && ( \ !defined(BOOST_MSVC) || (BOOST_MSVC < 1800) \ ) #include #include #define BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE ::boost::fusion::list #else #include #if defined(BOOST_FUSION_HAS_VARIADIC_DEQUE) #include #include #define BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE ::boost::fusion::deque #else #include #define BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE ::boost::mpl::vector #endif // BOOST_FUSION_HAS_VARIADIC_DEQUE #endif // BOOST_FUSION_HAS_VARIADIC_LIST #endif // BOOST_PARAMETER_CAN_USE_MP11 #endif // BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE namespace boost { namespace parameter { template struct parameters { typedef BOOST_PARAMETER_VARIADIC_MPL_SEQUENCE parameter_spec; typedef typename ::boost::parameter::aux ::make_deduced_list::type deduced_list; // If the elements of NamedList match the criteria of overload // resolution, returns a type which can be constructed from // parameters. Otherwise, this is not a valid metafunction // (no nested ::type). template struct match_base #if !defined(BOOST_PARAMETER_CAN_USE_MP11) : ::boost::mpl::if_< typename ::boost::parameter::aux::match_parameters_base_cond< ArgumentPackAndError , parameter_spec >::type , ::boost::mpl::identity< ::boost::parameter::parameters > , ::boost::parameter::void_ > #endif { #if defined(BOOST_PARAMETER_CAN_USE_MP11) using type = ::boost::mp11::mp_if< typename ::boost::parameter::aux::match_parameters_base_cond< ArgumentPackAndError , parameter_spec >::type , ::boost::mp11::mp_identity< ::boost::parameter::parameters > , ::boost::parameter::void_ >; #endif }; // Specializations are to be used as an optional argument // to eliminate overloads via SFINAE. template struct match : ::boost::parameter::parameters ::BOOST_NESTED_TEMPLATE match_base< typename ::boost::parameter::aux::make_arg_list< typename ::boost::parameter::aux ::make_parameter_spec_items::type , deduced_list , ::boost::parameter::aux::tag_keyword_arg // Don't emit errors when doing SFINAE. #if defined(BOOST_PARAMETER_CAN_USE_MP11) , ::boost::mp11::mp_false #else , ::boost::mpl::false_ #endif >::type >::type { }; // Metafunction that returns an ArgumentPack. template struct bind #if !defined(BOOST_PARAMETER_CAN_USE_MP11) : ::boost::mpl::first< typename ::boost::parameter::aux::make_arg_list< typename ::boost::parameter::aux ::make_parameter_spec_items::type , deduced_list , ::boost::parameter::aux::tag_template_keyword_arg >::type > #endif { #if defined(BOOST_PARAMETER_CAN_USE_MP11) using type = ::boost::mp11::mp_at_c< typename ::boost::parameter::aux::make_arg_list< typename ::boost::parameter::aux ::make_parameter_spec_items::type , deduced_list , ::boost::parameter::aux::tag_template_keyword_arg >::type , 0 >; #endif }; // The function call operator is used to build an arg_list that // labels the positional parameters and maintains whatever other // tags may have been specified by the caller. inline ::boost::parameter::aux::empty_arg_list operator()() const { return ::boost::parameter::aux::empty_arg_list(); } template #if defined(BOOST_PARAMETER_CAN_USE_MP11) inline ::boost::mp11::mp_at_c< #else inline typename ::boost::mpl::first< #endif typename ::boost::parameter::aux::make_arg_list< typename ::boost::parameter::aux ::make_parameter_spec_items::type , deduced_list , ::boost::parameter::aux::tag_keyword_arg >::type #if defined(BOOST_PARAMETER_CAN_USE_MP11) , 0 > #else >::type #endif operator()(A0&& a0, Args&& ...args) const { typedef typename ::boost::parameter::aux::make_arg_list< typename ::boost::parameter::aux ::make_parameter_spec_items::type , deduced_list , ::boost::parameter::aux::tag_keyword_arg >::type list_error_pair; #if defined(BOOST_PARAMETER_CAN_USE_MP11) using result_type = ::boost::mp11::mp_at_c; using error = ::boost::mp11::mp_at_c; #else typedef typename ::boost::mpl ::first::type result_type; typedef typename ::boost::mpl ::second::type error; #endif error(); return ::boost::parameter::aux ::arg_list_factory::reverse( ::std::forward(a0) , ::std::forward(args)... ); } }; }} // namespace boost::parameter #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #include #include #include #include #include #include #include #include #include #include #include #if ( \ BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < \ BOOST_PARAMETER_MAX_ARITY \ ) #include #include #include #include #include #include #include #include #endif #if !defined(BOOST_NO_SFINAE) && \ !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592)) #include #include #include #include #include #endif #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) #include #else #include #endif #include namespace boost { namespace parameter { template < typename PS0 , BOOST_PP_ENUM_SHIFTED( BOOST_PARAMETER_MAX_ARITY , BOOST_PARAMETER_template_args , PS ) > struct parameters { typedef typename BOOST_PARAMETER_build_deduced_list( BOOST_PARAMETER_MAX_ARITY , ::boost::parameter::aux::make_deduced_items , PS )::type deduced_list; // If the elements of NamedList match the criteria of overload // resolution, returns a type which can be constructed from // parameters. Otherwise, this is not a valid metafunction // (no nested ::type). #if !defined(BOOST_NO_SFINAE) && \ !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592)) // If NamedList satisfies the PS0, PS1, ..., this is a metafunction // returning parameters. Otherwise it has no nested ::type. template struct match_base : ::boost::mpl::if_< // ::boost::mpl::and_< // aux::satisfies_requirements_of // , ::boost::mpl::and_< // aux::satisfies_requirements_of... // ..., ::boost::mpl::true_ // ...> > typename BOOST_PP_REPEAT( BOOST_PARAMETER_MAX_ARITY , BOOST_PARAMETER_satisfies_begin , PS ) ::boost::is_same< typename ::boost::mpl ::second::type , ::boost::parameter::void_ > BOOST_PP_REPEAT( BOOST_PARAMETER_MAX_ARITY , BOOST_PARAMETER_satisfies_end , ::boost::mpl::false_ )::type , ::boost::mpl::identity< ::boost::parameter::parameters< BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS) > > , ::boost::parameter::void_ > { }; #endif // SFINAE enabled, not Borland // Specializations are to be used as an optional argument // to eliminate overloads via SFINAE. template < #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) // Borland simply can't handle default arguments in member // class templates. People wishing to write portable code can // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments. BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, typename A) #else BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PARAMETER_MAX_ARITY , typename A , = ::boost::parameter::void_ BOOST_PP_INTERCEPT ) #endif > struct match #if !defined(BOOST_NO_SFINAE) && \ !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592)) : ::boost::parameter::parameters< BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS) >::BOOST_NESTED_TEMPLATE match_base< typename ::boost::parameter::aux::make_arg_list< typename BOOST_PARAMETER_build_arg_list( BOOST_PARAMETER_MAX_ARITY , ::boost::parameter::aux::make_items , PS , A )::type , deduced_list , ::boost::parameter::aux::tag_keyword_arg // Don't emit errors when doing SFINAE. , ::boost::mpl::false_ >::type >::type { }; #else { typedef ::boost::parameter::parameters< BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS) > type; }; #endif // SFINAE enabled, not Borland // Metafunction that returns an ArgumentPack. // TODO, bind has to instantiate the error type in the result // of make_arg_list. template < #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) // Borland simply can't handle default arguments in member // class templates. People wishing to write portable code can // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments. BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, typename A) #else BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PARAMETER_MAX_ARITY , typename A , = ::boost::parameter::void_ BOOST_PP_INTERCEPT ) #endif > struct bind { typedef typename ::boost::parameter::aux::make_arg_list< typename BOOST_PARAMETER_build_arg_list( BOOST_PARAMETER_MAX_ARITY , ::boost::parameter::aux::make_items , PS , A )::type , deduced_list , ::boost::parameter::aux::tag_template_keyword_arg >::type result; typedef typename ::boost::mpl::first::type type; }; BOOST_PP_REPEAT( BOOST_PARAMETER_MAX_ARITY , BOOST_PARAMETER_forward_typedef , (PS)(parameter_spec) ) // The function call operator is used to build an arg_list that // labels the positional parameters and maintains whatever other // tags may have been specified by the caller. // // !!!NOTE!!! // // The make_arg_list<> metafunction produces a reversed arg_list, // so pass the arguments to the arg_list constructor reversed in turn. inline ::boost::parameter::aux::empty_arg_list operator()() const { return ::boost::parameter::aux::empty_arg_list(); } #if (0 < BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY) BOOST_PP_REPEAT( BOOST_PP_MIN( BOOST_PP_INC(BOOST_PARAMETER_MAX_ARITY) , BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY ) , BOOST_PARAMETER_AUX_PP_BINARY_SEQ_FOR_EACH_Z , (BOOST_PARAMETER_function_call_op_overload_R)(_) ) #if ( \ BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < \ BOOST_PARAMETER_MAX_ARITY \ ) #define BOOST_PP_ITERATION_PARAMS_1 \ (3,( \ BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \ , BOOST_PARAMETER_MAX_ARITY \ , \ )) #include BOOST_PP_ITERATE() #endif #else // (0 == BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY) template inline typename ::boost::mpl::first< typename ::boost::parameter::aux::make_arg_list< ::boost::parameter::aux::item< PS0,A0 > , deduced_list , ::boost::parameter::aux::tag_keyword_arg_ref >::type >::type operator()(A0& a0) const { typedef typename ::boost::parameter::aux::make_arg_list< ::boost::parameter::aux::item< PS0,A0 > , deduced_list , ::boost::parameter::aux::tag_keyword_arg_ref >::type result; typedef typename ::boost::mpl::first::type result_type; typedef typename ::boost::mpl::second::type error; error(); return result_type( a0 // , void_(), void_(), void_() ... BOOST_PP_ENUM_TRAILING_PARAMS( BOOST_PP_SUB(BOOST_PARAMETER_COMPOSE_MAX_ARITY, 1) , ::boost::parameter::aux::void_reference() BOOST_PP_INTERCEPT ) ); } template inline typename ::boost::mpl::first< typename ::boost::parameter::aux::make_arg_list< ::boost::parameter::aux::item< PS0,A0 , ::boost::parameter::aux::item< PS1,A1 > > , deduced_list , ::boost::parameter::aux::tag_keyword_arg_ref >::type >::type operator()(A0& a0, A1& a1) const { typedef typename ::boost::parameter::aux::make_arg_list< ::boost::parameter::aux::item< PS0,A0 , ::boost::parameter::aux::item< PS1,A1 > > , deduced_list , ::boost::parameter::aux::tag_keyword_arg >::type result; typedef typename ::boost::mpl::first::type result_type; typedef typename ::boost::mpl::second::type error; error(); return result_type( a1 , a0 // , void_(), void_() ... BOOST_PP_ENUM_TRAILING_PARAMS( BOOST_PP_SUB(BOOST_PARAMETER_COMPOSE_MAX_ARITY, 2) , ::boost::parameter::aux::void_reference() BOOST_PP_INTERCEPT ) ); } #if (2 < BOOST_PARAMETER_MAX_ARITY) // Higher arities are handled by the preprocessor #define BOOST_PP_ITERATION_PARAMS_1 \ (3,( \ 3 \ , BOOST_PARAMETER_MAX_ARITY \ , \ )) #include BOOST_PP_ITERATE() #endif #endif // exponential overloads }; }} // namespace boost::parameter #include #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING #endif // include guard