12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331 |
- // 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 BOOST_PARAMETER_AUX_ARG_LIST_HPP
- #define BOOST_PARAMETER_AUX_ARG_LIST_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 <typename T>
- struct get_reference
- {
- typedef typename T::reference type;
- };
- }}} // namespace boost::parameter::aux
- #include <boost/parameter/config.hpp>
- #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 <boost/parameter/aux_/void.hpp>
- #include <boost/parameter/aux_/yesno.hpp>
- #include <boost/parameter/aux_/result_of0.hpp>
- #include <boost/parameter/aux_/default.hpp>
- #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
- #include <utility>
- #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>
- #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 <typename ...Args>
- 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 <typename KW, typename Default, typename Reference>
- struct apply
- {
- typedef Default type;
- };
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- template <typename KW, typename Default, typename Reference>
- using fn = Default;
- #endif
- };
- // Terminator for has_key, indicating that the keyword is unique.
- template <typename KW>
- 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 <typename K, typename Default>
- inline BOOST_CONSTEXPR Default&
- operator[](::boost::parameter::aux::default_<K,Default> x) const
- {
- return x.value;
- }
- template <typename K, typename Default>
- inline BOOST_CONSTEXPR Default&&
- operator[](::boost::parameter::aux::default_r_<K,Default> x) const
- {
- return ::std::forward<Default>(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 <typename K, typename F>
- inline BOOST_CONSTEXPR
- typename ::boost::parameter::aux::result_of0<F>::type
- operator[](BOOST_PARAMETER_lazy_default_fallback<K,F> 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 <typename ParameterRequirements, typename ArgPack>
- 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 <boost/parameter/aux_/preprocessor/nullptr.hpp>
- #include <boost/parameter/aux_/yesno.hpp>
- #include <boost/parameter/aux_/is_maybe.hpp>
- #include <boost/parameter/aux_/tagged_argument_fwd.hpp>
- #include <boost/parameter/aux_/parameter_requirements.hpp>
- #include <boost/parameter/aux_/augment_predicate.hpp>
- #include <boost/parameter/keyword_fwd.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/mpl/eval_if.hpp>
- #include <boost/mpl/apply_wrap.hpp>
- #include <boost/mpl/assert.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/core/enable_if.hpp>
- 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<typename TaggedArg::value_type>::type;
- #else
- typedef typename ::boost::parameter::aux
- ::is_maybe<typename TaggedArg::value_type>::type _holds_maybe;
- #endif
- TaggedArg arg; // Stores the argument
- public:
- typedef TaggedArg tagged_arg;
- typedef ::boost::parameter::aux::arg_list<TaggedArg,Next> 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<typename TaggedArg::value_type>
- , ::boost::parameter::aux::get_reference<TaggedArg>
- >::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<typename TaggedArg::value_type>
- , ::boost::parameter::aux::get_reference<TaggedArg>
- >::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 <typename A0>
- 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>(a0))
- {
- }
- template <typename ...Args>
- 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>(args)...
- )
- , arg(::boost::parameter::aux::void_reference())
- {
- }
- template <typename A0, typename A1, typename ...Args>
- 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>(a1)
- , ::std::forward<Args>(args)...
- )
- , arg(::std::forward<A0>(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 <typename KW, typename Default, typename Reference>
- struct apply
- {
- typedef typename ::boost::mpl::eval_if<
- ::boost::is_same<KW,key_type>
- , ::boost::mpl::if_<Reference,reference,value_type>
- , ::boost::mpl
- ::apply_wrap3<next_binding,KW,Default,Reference>
- >::type type;
- };
- #if defined(BOOST_PARAMETER_CAN_USE_MP11)
- template <typename KW, typename Default, typename Reference>
- using fn = ::boost::mp11::mp_if<
- ::std::is_same<KW,key_type>
- , ::boost::mp11::mp_if<Reference,reference,value_type>
- , ::boost::mp11::mp_apply_q<
- next_binding
- , ::boost::mp11::mp_list<KW,Default,Reference>
- >
- >;
- #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<key_type*>(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<T>.
- template <typename D>
- 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 <typename D>
- 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<key_type> 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 <typename Default>
- inline BOOST_CONSTEXPR reference
- operator[](
- ::boost::parameter::aux::default_<key_type,Default> const& d
- ) const
- {
- return this->get_default(d, _holds_maybe());
- }
- template <typename Default>
- inline BOOST_CONSTEXPR reference
- operator[](
- ::boost::parameter::aux::default_r_<key_type,Default> const& d
- ) const
- {
- return this->get_default(d, _holds_maybe());
- }
- template <typename Default>
- inline BOOST_CONSTEXPR reference
- operator[](
- BOOST_PARAMETER_lazy_default_fallback<key_type,Default> 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 <typename HasDefault, typename Predicate, typename ArgPack>
- 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 <typename KW, typename T2>
- inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
- ::boost::parameter::aux::tagged_argument<KW,T2>
- , self
- >
- operator,(
- ::boost::parameter::aux::tagged_argument<KW,T2> const& x
- ) const
- {
- return ::boost::parameter::aux::arg_list<
- ::boost::parameter::aux::tagged_argument<KW,T2>
- , self
- >(x, *this);
- }
- template <typename KW, typename T2>
- inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
- ::boost::parameter::aux::tagged_argument_rref<KW,T2>
- , self
- >
- operator,(
- ::boost::parameter::aux::tagged_argument_rref<KW,T2> const& x
- ) const
- {
- return ::boost::parameter::aux::arg_list<
- ::boost::parameter::aux::tagged_argument_rref<KW,T2>
- , 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 <boost/preprocessor/repetition/enum_params.hpp>
- #include <boost/preprocessor/facilities/intercept.hpp>
- 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 <typename KW, typename Default, typename Reference>
- struct apply
- {
- typedef Default type;
- };
- };
- // Terminator for has_key, indicating that the keyword is unique.
- template <typename KW>
- static ::boost::parameter::aux::no_tag has_key(KW*);
- #if BOOST_WORKAROUND(BOOST_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 <typename KW>
- 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 <typename K, typename Default>
- inline BOOST_CONSTEXPR Default&
- operator[](::boost::parameter::aux::default_<K,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 <typename K, typename F>
- inline BOOST_CONSTEXPR
- typename ::boost::parameter::aux::result_of0<F>::type
- operator[](BOOST_PARAMETER_lazy_default_fallback<K,F> 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 <typename ParameterRequirements, typename ArgPack>
- 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 <boost/parameter/aux_/yesno.hpp>
- #include <boost/parameter/aux_/is_maybe.hpp>
- #include <boost/parameter/aux_/tagged_argument_fwd.hpp>
- #include <boost/parameter/aux_/parameter_requirements.hpp>
- #include <boost/parameter/aux_/augment_predicate.hpp>
- #include <boost/parameter/keyword_fwd.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/mpl/eval_if.hpp>
- #include <boost/mpl/apply_wrap.hpp>
- #include <boost/mpl/assert.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/preprocessor/repetition/enum_binary_params.hpp>
- #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
- #if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
- #include <boost/core/enable_if.hpp>
- #endif
- #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
- #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
- #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<typename TaggedArg::value_type>::type _holds_maybe;
- TaggedArg arg; // Stores the argument
- public:
- typedef TaggedArg tagged_arg;
- typedef ::boost::parameter::aux::arg_list<TaggedArg,Next> self;
- typedef typename TaggedArg::key_type key_type;
- typedef typename ::boost::mpl::eval_if<
- _holds_maybe
- , ::boost::parameter::aux
- ::get_reference<typename TaggedArg::value_type>
- , ::boost::parameter::aux::get_reference<TaggedArg>
- >::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 <typename KW, typename Default, typename Reference>
- struct apply
- {
- typedef typename ::boost::mpl::eval_if<
- ::boost::is_same<KW,key_type>
- , ::boost::mpl::if_<Reference,reference,value_type>
- , ::boost::mpl::apply_wrap3<
- next_binding
- , KW
- , Default
- , Reference
- >
- >::type type;
- };
- };
- #if !BOOST_WORKAROUND(BOOST_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<key_type*>(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<key_type*>(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<T>.
- template <typename D>
- inline BOOST_CONSTEXPR reference
- get_default(D const&, ::boost::mpl::false_) const
- {
- return this->arg.get_value();
- }
- template <typename D>
- 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(BOOST_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 <typename KW>
- struct apply
- {
- typedef typename ::boost::mpl::eval_if<
- ::boost::is_same<KW,key_type>
- , ::boost::mpl::identity<
- ::boost::parameter::aux::arg_list<TaggedArg,Next>
- >
- , ::boost::mpl::apply_wrap1<next_key_owner,KW>
- >::type type;
- };
- };
- // Outer indexing operators that dispatch to the right node's
- // get() function.
- template <typename KW>
- inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
- binding
- , KW
- , ::boost::parameter::void_
- , ::boost::mpl::true_
- >::type
- operator[](::boost::parameter::keyword<KW> const& x) const
- {
- typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const&
- sublist = *this;
- return sublist.get(x);
- }
- template <typename KW, typename Default>
- inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
- binding
- , KW
- , Default&
- , ::boost::mpl::true_
- >::type
- operator[](
- ::boost::parameter::aux::default_<KW,Default> const& x
- ) const
- {
- typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const&
- sublist = *this;
- return sublist.get(x);
- }
- template <typename KW, typename F>
- inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
- binding
- , KW
- , typename ::boost::parameter::aux::result_of0<F>::type
- , ::boost::mpl::true_
- >::type
- operator[](
- BOOST_PARAMETER_lazy_default_fallback<KW,F> const& x
- ) const
- {
- typename ::boost::mpl::apply_wrap1<key_owner,KW>::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<key_type> const&) const
- {
- BOOST_MPL_ASSERT_NOT((_holds_maybe));
- return this->arg.get_value();
- }
- template <typename Default>
- inline BOOST_CONSTEXPR reference
- get(
- ::boost::parameter::aux::default_<key_type,Default> const& d
- ) const
- {
- return this->get_default(d, _holds_maybe());
- }
- template <typename Default>
- inline BOOST_CONSTEXPR reference
- get(
- BOOST_PARAMETER_lazy_default_fallback<key_type,Default> const&
- ) const
- {
- return this->arg.get_value();
- }
- #else // !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
- inline BOOST_CONSTEXPR reference
- operator[](::boost::parameter::keyword<key_type> const&) const
- {
- BOOST_MPL_ASSERT_NOT((_holds_maybe));
- return this->arg.get_value();
- }
- template <typename Default>
- inline BOOST_CONSTEXPR reference
- operator[](
- ::boost::parameter::aux::default_<key_type,Default> const& d
- ) const
- {
- return this->get_default(d, _holds_maybe());
- }
- template <typename Default>
- inline BOOST_CONSTEXPR reference
- operator[](
- BOOST_PARAMETER_lazy_default_fallback<key_type,Default> 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 <typename HasDefault, typename Predicate, typename ArgPack>
- 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 <typename KW, typename T2>
- inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
- ::boost::parameter::aux::tagged_argument<KW,T2>
- , self
- >
- operator,(
- ::boost::parameter::aux::tagged_argument<KW,T2> const& x
- ) const
- {
- return ::boost::parameter::aux::arg_list<
- ::boost::parameter::aux::tagged_argument<KW,T2>
- , 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 <typename ...ArgTuples>
- struct arg_list_cons;
- template <>
- struct arg_list_cons<>
- {
- using type = ::boost::parameter::aux::empty_arg_list;
- };
- template <typename ArgTuple0, typename ...Tuples>
- struct arg_list_cons<ArgTuple0,Tuples...>
- {
- using type = ::boost::parameter::aux::arg_list<
- typename ArgTuple0::tagged_arg
- , typename ::boost::parameter::aux::arg_list_cons<Tuples...>::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 <typename ...ArgTuples>
- class flat_like_arg_list
- : public ::boost::parameter::aux::arg_list_cons<ArgTuples...>::type
- {
- using _base_type = typename ::boost::parameter::aux
- ::arg_list_cons<ArgTuples...>::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 <typename ...Args>
- inline BOOST_CONSTEXPR flat_like_arg_list(Args&&... args)
- : _base_type(::std::forward<Args>(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 <typename TaggedArg>
- 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<typename TaggedArg::base_type const&>(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 <typename ...Args>
- inline BOOST_CONSTEXPR flat_like_arg_list(Args&&... args)
- : _base_type(::std::forward<Args>(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 <typename TaggedArg>
- 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<typename TaggedArg::base_type const&>(x)
- , static_cast<_base_type const&>(*this)
- );
- }
- };
- }}} // namespace boost::parameter::aux
- #endif // BOOST_PARAMETER_CAN_USE_MP11
- #include <boost/mpl/iterator_tags.hpp>
- namespace boost { namespace parameter { namespace aux {
- // MPL sequence support
- template <typename ArgumentPack>
- struct arg_list_iterator
- {
- typedef ::boost::mpl::forward_iterator_tag category;
- // The incremented iterator
- typedef ::boost::parameter::aux
- ::arg_list_iterator<typename ArgumentPack::tail_type> 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 <boost/mpl/begin_end_fwd.hpp>
- // MPL sequence support
- namespace boost { namespace mpl {
- template <>
- struct begin_impl< ::boost::parameter::aux::arg_list_tag>
- {
- template <typename S>
- struct apply
- {
- typedef ::boost::parameter::aux::arg_list_iterator<S> type;
- };
- };
- template <>
- struct end_impl< ::boost::parameter::aux::arg_list_tag>
- {
- template <typename>
- struct apply
- {
- typedef ::boost::parameter::aux::arg_list_iterator<
- ::boost::parameter::aux::empty_arg_list
- > type;
- };
- };
- }} // namespace boost::mpl
- #include <boost/parameter/value_type.hpp>
- #include <boost/mpl/has_key_fwd.hpp>
- #include <boost/type_traits/is_void.hpp>
- namespace boost { namespace mpl {
- template <>
- struct has_key_impl< ::boost::parameter::aux::arg_list_tag>
- {
- template <typename ArgList, typename Keyword>
- struct apply
- {
- typedef typename ::boost::mpl::if_<
- ::boost::is_void<
- typename ::boost::parameter
- ::value_type<ArgList,Keyword,void>::type
- >
- , ::boost::mpl::false_
- , ::boost::mpl::true_
- >::type type;
- };
- };
- }} // namespace boost::mpl
- #include <boost/mpl/count_fwd.hpp>
- #include <boost/mpl/int.hpp>
- namespace boost { namespace mpl {
- template <>
- struct count_impl< ::boost::parameter::aux::arg_list_tag>
- {
- template <typename ArgList, typename Keyword>
- struct apply
- {
- typedef typename ::boost::mpl::if_<
- ::boost::is_void<
- typename ::boost::parameter
- ::value_type<ArgList,Keyword,void>::type
- >
- , ::boost::mpl::int_<0>
- , ::boost::mpl::int_<1>
- >::type type;
- };
- };
- }} // namespace boost::mpl
- #include <boost/mpl/key_type_fwd.hpp>
- #include <boost/mpl/identity.hpp>
- namespace boost { namespace mpl {
- template <>
- struct key_type_impl< ::boost::parameter::aux::arg_list_tag>
- {
- template <typename ArgList, typename Keyword>
- struct apply
- {
- typedef typename ::boost::mpl::eval_if<
- ::boost::is_void<
- typename ::boost::parameter
- ::value_type<ArgList,Keyword,void>::type
- >
- , void
- , ::boost::mpl::identity<Keyword>
- >::type type;
- };
- };
- }} // namespace boost::mpl
- #include <boost/mpl/value_type_fwd.hpp>
- 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 <boost/mpl/at_fwd.hpp>
- 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 <boost/mpl/order_fwd.hpp>
- #include <boost/mpl/void.hpp>
- #include <boost/mpl/find.hpp>
- #include <boost/mpl/distance.hpp>
- namespace boost { namespace mpl {
- template <>
- struct order_impl< ::boost::parameter::aux::arg_list_tag>
- {
- template <typename ArgList, typename Keyword>
- struct apply
- {
- typedef typename ::boost::mpl::find<ArgList,Keyword>::type Itr;
- typedef typename ::boost::mpl::eval_if<
- ::boost::is_void<
- typename ::boost::parameter
- ::value_type<ArgList,Keyword,void>::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
|