// Copyright Daniel Wallin, David Abrahams 2005. // 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 ARG_LIST_050329_HPP #define ARG_LIST_050329_HPP namespace boost { namespace parameter { namespace aux { // // Structures used to build the tuple of actual arguments. The tuple is a // nested cons-style list of arg_list specializations terminated by an // empty_arg_list. // // Each specialization of arg_list is derived from its successor in the // list type. This feature is used along with using declarations to build // member function overload sets that can match against keywords. // // MPL sequence support struct arg_list_tag; template struct get_reference { typedef typename T::reference type; }; }}} // namespace boost::parameter::aux #include #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) namespace boost { namespace parameter { namespace aux { struct value_type_is_void { }; struct value_type_is_not_void { }; }}} // namespace boost::parameter::aux #endif #include #include #include #include #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #include #if defined(BOOST_PARAMETER_CAN_USE_MP11) #include #include #include #include #endif namespace boost { namespace parameter { namespace aux { // Terminates arg_list<> and represents an empty list. Since this is just // the terminating case, you might want to look at arg_list first to get a // feel for what's really happening here. struct empty_arg_list { struct tagged_arg { typedef ::boost::parameter::void_ value_type; }; // Variadic constructor also serves as default constructor. template inline BOOST_CONSTEXPR empty_arg_list(Args&&...) { } // A metafunction class that, given a keyword and a default type, // returns the appropriate result type for a keyword lookup given // that default. struct binding { template struct apply { typedef Default type; }; #if defined(BOOST_PARAMETER_CAN_USE_MP11) template using fn = Default; #endif }; // Terminator for has_key, indicating that the keyword is unique. template static ::boost::parameter::aux::no_tag has_key(KW*); // If either of these operators are called, it means there is no // argument in the list that matches the supplied keyword. Just // return the default value. template inline BOOST_CONSTEXPR Default& operator[](::boost::parameter::aux::default_ x) const { return x.value; } template inline BOOST_CONSTEXPR Default&& operator[](::boost::parameter::aux::default_r_ x) const { return ::std::forward(x.value); } // If this operator is called, it means there is no argument in the // list that matches the supplied keyword. Just evaluate and return // the default value. template inline BOOST_CONSTEXPR typename ::boost::parameter::aux::result_of0::type operator[](BOOST_PARAMETER_lazy_default_fallback x) const { return x.compute_default(); } // No argument corresponding to ParameterRequirements::key_type // was found if we match this overload, so unless that parameter // has a default, we indicate that the actual arguments don't // match the function's requirements. template static typename ParameterRequirements::has_default satisfies(ParameterRequirements*, ArgPack*); // MPL sequence support typedef ::boost::parameter::aux::empty_arg_list type; // convenience // For dispatching to sequence intrinsics typedef ::boost::parameter::aux::arg_list_tag tag; }; }}} // namespace boost::parameter::aux #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace parameter { namespace aux { // A tuple of tagged arguments, terminated with empty_arg_list. Every // TaggedArg is an instance of tagged_argument<> or // tagged_argument_rref<>. template < typename TaggedArg , typename Next = ::boost::parameter::aux::empty_arg_list #if defined(BOOST_PARAMETER_CAN_USE_MP11) , typename EmitsErrors = ::boost::mp11::mp_true #else , typename EmitsErrors = ::boost::mpl::true_ #endif > class arg_list : public Next { #if defined(BOOST_PARAMETER_CAN_USE_MP11) using _holds_maybe = typename ::boost::parameter::aux ::is_maybe::type; #else typedef typename ::boost::parameter::aux ::is_maybe::type _holds_maybe; #endif TaggedArg arg; // Stores the argument public: typedef TaggedArg tagged_arg; typedef ::boost::parameter::aux::arg_list self; typedef typename TaggedArg::key_type key_type; #if defined(BOOST_PARAMETER_CAN_USE_MP11) using reference = typename ::boost::mp11::mp_if< _holds_maybe , ::boost::parameter::aux ::get_reference , ::boost::parameter::aux::get_reference >::type; using value_type = ::boost::mp11 ::mp_if<_holds_maybe,reference,typename TaggedArg::value_type>; #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) typedef typename ::boost::mpl::eval_if< _holds_maybe , ::boost::parameter::aux ::get_reference , ::boost::parameter::aux::get_reference >::type reference; typedef typename ::boost::mpl::if_< _holds_maybe , reference , typename TaggedArg::value_type >::type value_type; #endif // BOOST_PARAMETER_CAN_USE_MP11 // Create a new list by prepending arg to a copy of tail. Used when // incrementally building this structure with the comma operator. inline BOOST_CONSTEXPR arg_list( TaggedArg const& head , Next const& tail ) : Next(tail), arg(head) { } // Store the arguments in successive nodes of this list. // Use tag dispatching to determine whether to forward all arguments // to the Next constructor, or store the first argument and forward // the rest. -- Cromwell D. Enage template inline BOOST_CONSTEXPR arg_list( ::boost::parameter::aux::value_type_is_not_void , A0&& a0 ) : Next( #if defined(BOOST_PARAMETER_CAN_USE_MP11) ::boost::mp11::mp_if< ::std::is_same< #else typename ::boost::mpl::if_< ::boost::is_same< #endif typename Next::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 ) , arg(::std::forward(a0)) { } template inline BOOST_CONSTEXPR arg_list( ::boost::parameter::aux::value_type_is_void , Args&&... args ) : Next( #if defined(BOOST_PARAMETER_CAN_USE_MP11) ::boost::mp11::mp_if< ::std::is_same< #else typename ::boost::mpl::if_< ::boost::is_same< #endif typename Next::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(args)... ) , arg(::boost::parameter::aux::void_reference()) { } template inline BOOST_CONSTEXPR arg_list( ::boost::parameter::aux::value_type_is_not_void , A0&& a0 , A1&& a1 , Args&&... args ) : Next( #if defined(BOOST_PARAMETER_CAN_USE_MP11) ::boost::mp11::mp_if< ::std::is_same< #else typename ::boost::mpl::if_< ::boost::is_same< #endif typename Next::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(a1) , ::std::forward(args)... ) , arg(::std::forward(a0)) { } // A metafunction class that, given a keyword and a default type, // returns the appropriate result type for a keyword lookup given // that default. struct binding { typedef typename Next::binding next_binding; template struct apply { typedef typename ::boost::mpl::eval_if< ::boost::is_same , ::boost::mpl::if_ , ::boost::mpl ::apply_wrap3 >::type type; }; #if defined(BOOST_PARAMETER_CAN_USE_MP11) template using fn = ::boost::mp11::mp_if< ::std::is_same , ::boost::mp11::mp_if , ::boost::mp11::mp_apply_q< next_binding , ::boost::mp11::mp_list > >; #endif }; // Overload for key_type, so the assert below will fire // if the same keyword is used again. static ::boost::parameter::aux::yes_tag has_key(key_type*); using Next::has_key; private: #if defined(BOOST_PARAMETER_CAN_USE_MP11) using _has_unique_key = ::boost::mp11::mp_bool< #else typedef ::boost::mpl::bool_< #endif sizeof( Next::has_key( static_cast(BOOST_PARAMETER_AUX_PP_NULLPTR) ) ) == sizeof(::boost::parameter::aux::no_tag) #if defined(BOOST_PARAMETER_CAN_USE_MP11) >; #else > _has_unique_key; #endif #if defined(BOOST_PARAMETER_CAN_USE_MP11) static_assert( !(EmitsErrors::value) || (_has_unique_key::value) , "duplicate keyword" ); #else BOOST_MPL_ASSERT_MSG( !(EmitsErrors::value) || (_has_unique_key::value) , duplicate_keyword , (key_type) ); #endif // // Begin implementation of indexing operators // for looking up specific arguments by name. // // Helpers that handle the case when TaggedArg is empty. template inline BOOST_CONSTEXPR reference #if defined(BOOST_PARAMETER_CAN_USE_MP11) get_default(D const&, ::boost::mp11::mp_false) const #else get_default(D const&, ::boost::mpl::false_) const #endif { return this->arg.get_value(); } template inline BOOST_CONSTEXPR reference #if defined(BOOST_PARAMETER_CAN_USE_MP11) get_default(D const& d, ::boost::mp11::mp_true) const #else get_default(D const& d, ::boost::mpl::true_) const #endif { return ( this->arg.get_value() ? this->arg.get_value().get() : this->arg.get_value().construct(d.value) ); } public: inline BOOST_CONSTEXPR reference operator[](::boost::parameter::keyword const&) const { #if !defined(BOOST_NO_CXX14_CONSTEXPR) #if defined(BOOST_PARAMETER_CAN_USE_MP11) static_assert(!_holds_maybe::value, "must not hold maybe"); #elif !( \ BOOST_WORKAROUND(BOOST_GCC, >= 40700) && \ BOOST_WORKAROUND(BOOST_GCC, < 40900) \ ) && !BOOST_WORKAROUND(BOOST_GCC, >= 50000) && \ !BOOST_WORKAROUND(BOOST_MSVC, < 1910) BOOST_MPL_ASSERT_NOT((_holds_maybe)); #endif #endif return this->arg.get_value(); } template inline BOOST_CONSTEXPR reference operator[]( ::boost::parameter::aux::default_ const& d ) const { return this->get_default(d, _holds_maybe()); } template inline BOOST_CONSTEXPR reference operator[]( ::boost::parameter::aux::default_r_ const& d ) const { return this->get_default(d, _holds_maybe()); } template inline BOOST_CONSTEXPR reference operator[]( BOOST_PARAMETER_lazy_default_fallback const& ) const { #if !defined(BOOST_NO_CXX14_CONSTEXPR) #if defined(BOOST_PARAMETER_CAN_USE_MP11) static_assert(!_holds_maybe::value, "must not hold maybe"); #elif !( \ BOOST_WORKAROUND(BOOST_GCC, >= 40700) && \ BOOST_WORKAROUND(BOOST_GCC, < 40900) \ ) && !BOOST_WORKAROUND(BOOST_GCC, >= 50000) && \ !BOOST_WORKAROUND(BOOST_MSVC, < 1910) BOOST_MPL_ASSERT_NOT((_holds_maybe)); #endif #endif return this->arg.get_value(); } // Builds an overload set including operator[]s defined // in base classes. using Next::operator[]; // // End of indexing support // // For parameter_requirements matching this node's key_type, return // a bool constant wrapper indicating whether the requirements are // satisfied by TaggedArg. Used only for compile-time computation // and never really called, so a declaration is enough. template static typename ::boost::lazy_enable_if< #if defined(BOOST_PARAMETER_CAN_USE_MP11) ::boost::mp11::mp_if< EmitsErrors , ::boost::mp11::mp_true , _has_unique_key > , ::boost::parameter::aux::augment_predicate_mp11< #else typename ::boost::mpl::if_< EmitsErrors , ::boost::mpl::true_ , _has_unique_key >::type , ::boost::parameter::aux::augment_predicate< #endif Predicate , reference , key_type , value_type , ArgPack > >::type satisfies( ::boost::parameter::aux::parameter_requirements< key_type , Predicate , HasDefault >* , ArgPack* ); // Builds an overload set including satisfies functions defined // in base classes. using Next::satisfies; // Comma operator to compose argument list without using parameters<>. // Useful for argument lists with undetermined length. template inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument , self > operator,( ::boost::parameter::aux::tagged_argument const& x ) const { return ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument , self >(x, *this); } template inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument_rref , self > operator,( ::boost::parameter::aux::tagged_argument_rref const& x ) const { return ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument_rref , self >(x, *this); } // MPL sequence support typedef self type; // Convenience for users typedef Next tail_type; // For the benefit of iterators // For dispatching to sequence intrinsics typedef ::boost::parameter::aux::arg_list_tag tag; }; }}} // namespace boost::parameter::aux #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) #include #include namespace boost { namespace parameter { namespace aux { // Terminates arg_list<> and represents an empty list. Since this is just // the terminating case, you might want to look at arg_list first to get a // feel for what's really happening here. struct empty_arg_list { inline BOOST_CONSTEXPR empty_arg_list() { } // Constructor taking BOOST_PARAMETER_COMPOSE_MAX_ARITY empty_arg_list // arguments; this makes initialization. inline BOOST_CONSTEXPR empty_arg_list( BOOST_PP_ENUM_PARAMS( BOOST_PARAMETER_COMPOSE_MAX_ARITY , ::boost::parameter::void_ BOOST_PP_INTERCEPT ) ) { } // A metafunction class that, given a keyword and a default type, // returns the appropriate result type for a keyword lookup given // that default. struct binding { template struct apply { typedef Default type; }; }; // Terminator for has_key, indicating that the keyword is unique. template static ::boost::parameter::aux::no_tag has_key(KW*); #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // The overload set technique doesn't work with these older compilers, // so they need some explicit handholding. // A metafunction class that, given a keyword, returns the type of the // base sublist whose get() function can produce the value for that key. struct key_owner { template struct apply { typedef ::boost::parameter::aux::empty_arg_list type; }; }; #endif // Borland workarounds needed // If either of these operators are called, it means there is no // argument in the list that matches the supplied keyword. Just // return the default value. template inline BOOST_CONSTEXPR Default& operator[](::boost::parameter::aux::default_ x) const { return x.value; } // If this operator is called, it means there is no argument in the // list that matches the supplied keyword. Just evaluate and return // the default value. template inline BOOST_CONSTEXPR typename ::boost::parameter::aux::result_of0::type operator[](BOOST_PARAMETER_lazy_default_fallback x) const { return x.compute_default(); } // No argument corresponding to ParameterRequirements::key_type // was found if we match this overload, so unless that parameter // has a default, we indicate that the actual arguments don't // match the function's requirements. template static typename ParameterRequirements::has_default satisfies(ParameterRequirements*, ArgPack*); // MPL sequence support typedef ::boost::parameter::aux::empty_arg_list type; // convenience // For dispatching to sequence intrinsics typedef ::boost::parameter::aux::arg_list_tag tag; }; }}} // namespace boost::parameter::aux #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) #include #endif #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) #include #endif namespace boost { namespace parameter { namespace aux { // A tuple of tagged arguments, terminated with empty_arg_list. Every // TaggedArg is an instance of tagged_argument<>. template < typename TaggedArg , typename Next = ::boost::parameter::aux::empty_arg_list , typename EmitsErrors = ::boost::mpl::true_ > class arg_list : public Next { typedef typename ::boost::parameter::aux ::is_maybe::type _holds_maybe; TaggedArg arg; // Stores the argument public: typedef TaggedArg tagged_arg; typedef ::boost::parameter::aux::arg_list self; typedef typename TaggedArg::key_type key_type; typedef typename ::boost::mpl::eval_if< _holds_maybe , ::boost::parameter::aux ::get_reference , ::boost::parameter::aux::get_reference >::type reference; typedef typename ::boost::mpl::if_< _holds_maybe , reference , typename TaggedArg::value_type >::type value_type; // Create a new list by prepending arg to a copy of tail. Used when // incrementally building this structure with the comma operator. inline BOOST_CONSTEXPR arg_list( TaggedArg const& head , Next const& tail ) : Next(tail), arg(head) { } // Store the arguments in successive nodes of this list. template < // typename A0, typename A1, ... BOOST_PP_ENUM_PARAMS( BOOST_PARAMETER_COMPOSE_MAX_ARITY , typename A ) > inline BOOST_CONSTEXPR arg_list( // A0& a0, A1& a1, ... BOOST_PP_ENUM_BINARY_PARAMS( BOOST_PARAMETER_COMPOSE_MAX_ARITY , A , & a ) ) : Next( // a1, a2, ... BOOST_PP_ENUM_SHIFTED_PARAMS( BOOST_PARAMETER_COMPOSE_MAX_ARITY , a ) , ::boost::parameter::aux::void_reference() ) , arg(a0) { } // A metafunction class that, given a keyword and a default type, // returns the appropriate result type for a keyword lookup given // that default. struct binding { typedef typename Next::binding next_binding; template struct apply { typedef typename ::boost::mpl::eval_if< ::boost::is_same , ::boost::mpl::if_ , ::boost::mpl::apply_wrap3< next_binding , KW , Default , Reference > >::type type; }; }; #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // Overload for key_type, so the assert below will fire // if the same keyword is used again. static ::boost::parameter::aux::yes_tag has_key(key_type*); using Next::has_key; private: #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(BOOST_MSVC, < 1800) BOOST_MPL_ASSERT_MSG( sizeof( Next::has_key( static_cast(BOOST_PARAMETER_AUX_PP_NULLPTR) ) ) == sizeof(::boost::parameter::aux::no_tag) , duplicate_keyword , (key_type) ); #else typedef ::boost::mpl::bool_< sizeof( Next::has_key( static_cast(BOOST_PARAMETER_AUX_PP_NULLPTR) ) ) == sizeof(::boost::parameter::aux::no_tag) > _has_unique_key; BOOST_MPL_ASSERT_MSG( !(EmitsErrors::value) || (_has_unique_key::value) , duplicate_keyword , (key_type) ); #endif // SFINAE/MSVC workarounds needed #endif // Borland workarounds not needed private: // // Begin implementation of indexing operators // for looking up specific arguments by name. // // Helpers that handle the case when TaggedArg is empty. template inline BOOST_CONSTEXPR reference get_default(D const&, ::boost::mpl::false_) const { return this->arg.get_value(); } template inline BOOST_CONSTEXPR reference get_default(D const& d, ::boost::mpl::true_) const { return ( this->arg.get_value() ? this->arg.get_value().get() : this->arg.get_value().construct(d.value) ); } public: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) // These older compilers don't support the overload set creation // idiom well, so we need to do all the return type calculation // for the compiler and dispatch through an outer function template. // A metafunction class that, given a keyword, returns the base // sublist whose get() function can produce the value for that key. struct key_owner { typedef typename Next::key_owner next_key_owner; template struct apply { typedef typename ::boost::mpl::eval_if< ::boost::is_same , ::boost::mpl::identity< ::boost::parameter::aux::arg_list > , ::boost::mpl::apply_wrap1 >::type type; }; }; // Outer indexing operators that dispatch to the right node's // get() function. template inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< binding , KW , ::boost::parameter::void_ , ::boost::mpl::true_ >::type operator[](::boost::parameter::keyword const& x) const { typename ::boost::mpl::apply_wrap1::type const& sublist = *this; return sublist.get(x); } template inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< binding , KW , Default& , ::boost::mpl::true_ >::type operator[]( ::boost::parameter::aux::default_ const& x ) const { typename ::boost::mpl::apply_wrap1::type const& sublist = *this; return sublist.get(x); } template inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< binding , KW , typename ::boost::parameter::aux::result_of0::type , ::boost::mpl::true_ >::type operator[]( BOOST_PARAMETER_lazy_default_fallback const& x ) const { typename ::boost::mpl::apply_wrap1::type const& sublist = *this; return sublist.get(x); } // These just return the stored value; when empty_arg_list is reached, // indicating no matching argument was passed, the default is // returned, or if no default_ or lazy_default was passed, compilation // fails. inline BOOST_CONSTEXPR reference get(::boost::parameter::keyword const&) const { BOOST_MPL_ASSERT_NOT((_holds_maybe)); return this->arg.get_value(); } template inline BOOST_CONSTEXPR reference get( ::boost::parameter::aux::default_ const& d ) const { return this->get_default(d, _holds_maybe()); } template inline BOOST_CONSTEXPR reference get( BOOST_PARAMETER_lazy_default_fallback const& ) const { return this->arg.get_value(); } #else // !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) inline BOOST_CONSTEXPR reference operator[](::boost::parameter::keyword const&) const { BOOST_MPL_ASSERT_NOT((_holds_maybe)); return this->arg.get_value(); } template inline BOOST_CONSTEXPR reference operator[]( ::boost::parameter::aux::default_ const& d ) const { return this->get_default(d, _holds_maybe()); } template inline BOOST_CONSTEXPR reference operator[]( BOOST_PARAMETER_lazy_default_fallback const& ) const { BOOST_MPL_ASSERT_NOT((_holds_maybe)); return this->arg.get_value(); } // Builds an overload set including operator[]s defined // in base classes. using Next::operator[]; // // End of indexing support // // For parameter_requirements matching this node's key_type, return // a bool constant wrapper indicating whether the requirements are // satisfied by TaggedArg. Used only for compile-time computation // and never really called, so a declaration is enough. template static typename #if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) ::boost::lazy_enable_if< typename ::boost::mpl::if_< EmitsErrors , ::boost::mpl::true_ , _has_unique_key >::type, #endif ::boost::parameter::aux::augment_predicate< Predicate , reference , key_type , value_type , ArgPack #if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) > #endif >::type satisfies( ::boost::parameter::aux::parameter_requirements< key_type , Predicate , HasDefault >* , ArgPack* ); // Builds an overload set including satisfies functions defined // in base classes. using Next::satisfies; #endif // Borland workarounds needed // Comma operator to compose argument list without using parameters<>. // Useful for argument lists with undetermined length. template inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument , self > operator,( ::boost::parameter::aux::tagged_argument const& x ) const { return ::boost::parameter::aux::arg_list< ::boost::parameter::aux::tagged_argument , self >(x, *this); } // MPL sequence support typedef self type; // Convenience for users typedef Next tail_type; // For the benefit of iterators // For dispatching to sequence intrinsics typedef ::boost::parameter::aux::arg_list_tag tag; }; }}} // namespace boost::parameter::aux #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING #if defined(BOOST_PARAMETER_CAN_USE_MP11) namespace boost { namespace parameter { namespace aux { template struct arg_list_cons; template <> struct arg_list_cons<> { using type = ::boost::parameter::aux::empty_arg_list; }; template struct arg_list_cons { using type = ::boost::parameter::aux::arg_list< typename ArgTuple0::tagged_arg , typename ::boost::parameter::aux::arg_list_cons::type , typename ArgTuple0::emits_errors >; }; template < typename Keyword , typename TaggedArg , typename EmitsErrors = ::boost::mp11::mp_true > struct flat_like_arg_tuple { using tagged_arg = TaggedArg; using emits_errors = EmitsErrors; }; template class flat_like_arg_list : public ::boost::parameter::aux::arg_list_cons::type { using _base_type = typename ::boost::parameter::aux ::arg_list_cons::type; public: inline BOOST_CONSTEXPR flat_like_arg_list( typename _base_type::tagged_arg const& head , typename _base_type::tail_type const& tail ) : _base_type(head, tail) { } template inline BOOST_CONSTEXPR flat_like_arg_list(Args&&... args) : _base_type(::std::forward(args)...) { } using _base_type::operator[]; using _base_type::satisfies; // Comma operator to compose argument list without using parameters<>. // Useful for argument lists with undetermined length. template inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list< ::boost::parameter::aux::flat_like_arg_tuple< typename TaggedArg::base_type::key_type , typename TaggedArg::base_type > , ArgTuples... > operator,(TaggedArg const& x) const { return ::boost::parameter::aux::flat_like_arg_list< ::boost::parameter::aux::flat_like_arg_tuple< typename TaggedArg::base_type::key_type , typename TaggedArg::base_type > , ArgTuples... >( static_cast(x) , static_cast<_base_type const&>(*this) ); } }; template <> class flat_like_arg_list<> : public ::boost::parameter::aux::empty_arg_list { using _base_type = ::boost::parameter::aux::empty_arg_list; public: template inline BOOST_CONSTEXPR flat_like_arg_list(Args&&... args) : _base_type(::std::forward(args)...) { } using _base_type::operator[]; using _base_type::satisfies; // Comma operator to compose argument list without using parameters<>. // Useful for argument lists with undetermined length. template inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list< ::boost::parameter::aux::flat_like_arg_tuple< typename TaggedArg::base_type::key_type , typename TaggedArg::base_type > > operator,(TaggedArg const& x) const { return ::boost::parameter::aux::flat_like_arg_list< ::boost::parameter::aux::flat_like_arg_tuple< typename TaggedArg::base_type::key_type , typename TaggedArg::base_type > >( static_cast(x) , static_cast<_base_type const&>(*this) ); } }; }}} // namespace boost::parameter::aux #endif // BOOST_PARAMETER_CAN_USE_MP11 #include namespace boost { namespace parameter { namespace aux { // MPL sequence support template struct arg_list_iterator { typedef ::boost::mpl::forward_iterator_tag category; // The incremented iterator typedef ::boost::parameter::aux ::arg_list_iterator next; // dereferencing yields the key type typedef typename ArgumentPack::key_type type; }; template <> struct arg_list_iterator< ::boost::parameter::aux::empty_arg_list> { }; }}} // namespace boost::parameter::aux #include // MPL sequence support namespace boost { namespace mpl { template <> struct begin_impl< ::boost::parameter::aux::arg_list_tag> { template struct apply { typedef ::boost::parameter::aux::arg_list_iterator type; }; }; template <> struct end_impl< ::boost::parameter::aux::arg_list_tag> { template struct apply { typedef ::boost::parameter::aux::arg_list_iterator< ::boost::parameter::aux::empty_arg_list > type; }; }; }} // namespace boost::mpl #include #include #include namespace boost { namespace mpl { template <> struct has_key_impl< ::boost::parameter::aux::arg_list_tag> { template struct apply { typedef typename ::boost::mpl::if_< ::boost::is_void< typename ::boost::parameter ::value_type::type > , ::boost::mpl::false_ , ::boost::mpl::true_ >::type type; }; }; }} // namespace boost::mpl #include #include namespace boost { namespace mpl { template <> struct count_impl< ::boost::parameter::aux::arg_list_tag> { template struct apply { typedef typename ::boost::mpl::if_< ::boost::is_void< typename ::boost::parameter ::value_type::type > , ::boost::mpl::int_<0> , ::boost::mpl::int_<1> >::type type; }; }; }} // namespace boost::mpl #include #include namespace boost { namespace mpl { template <> struct key_type_impl< ::boost::parameter::aux::arg_list_tag> { template struct apply { typedef typename ::boost::mpl::eval_if< ::boost::is_void< typename ::boost::parameter ::value_type::type > , void , ::boost::mpl::identity >::type type; }; }; }} // namespace boost::mpl #include namespace boost { namespace mpl { template <> struct value_type_impl< ::boost::parameter::aux::arg_list_tag> : ::boost::mpl::key_type_impl< ::boost::parameter::aux::arg_list_tag> { }; }} // namespace boost::mpl #include namespace boost { namespace mpl { template <> struct at_impl< ::boost::parameter::aux::arg_list_tag> : ::boost::mpl::key_type_impl< ::boost::parameter::aux::arg_list_tag> { }; }} // namespace boost::mpl #include #include #include #include namespace boost { namespace mpl { template <> struct order_impl< ::boost::parameter::aux::arg_list_tag> { template struct apply { typedef typename ::boost::mpl::find::type Itr; typedef typename ::boost::mpl::eval_if< ::boost::is_void< typename ::boost::parameter ::value_type::type > , ::boost::mpl::identity< ::boost::mpl::void_> , ::boost::mpl::distance< Itr , ::boost::parameter::aux::arg_list_iterator< ::boost::parameter::aux::empty_arg_list > > >::type type; }; }; }} // namespace boost::mpl #endif // include guard