Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:20:38

0001 // Copyright Daniel Wallin, David Abrahams 2005.
0002 // Copyright Cromwell D. Enage 2017.
0003 // Distributed under the Boost Software License, Version 1.0.
0004 // (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_PARAMETER_AUX_ARG_LIST_HPP
0008 #define BOOST_PARAMETER_AUX_ARG_LIST_HPP
0009 
0010 namespace boost { namespace parameter { namespace aux {
0011 
0012     //
0013     // Structures used to build the tuple of actual arguments.  The tuple is a
0014     // nested cons-style list of arg_list specializations terminated by an
0015     // empty_arg_list.
0016     //
0017     // Each specialization of arg_list is derived from its successor in the
0018     // list type.  This feature is used along with using declarations to build
0019     // member function overload sets that can match against keywords.
0020     //
0021 
0022     // MPL sequence support
0023     struct arg_list_tag;
0024 
0025     template <typename T>
0026     struct get_reference
0027     {
0028         typedef typename T::reference type;
0029     };
0030 }}} // namespace boost::parameter::aux
0031 
0032 #include <boost/parameter/config.hpp>
0033 
0034 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
0035 
0036 namespace boost { namespace parameter { namespace aux {
0037 
0038     struct value_type_is_void
0039     {
0040     };
0041 
0042     struct value_type_is_not_void
0043     {
0044     };
0045 }}} // namespace boost::parameter::aux
0046 
0047 #endif
0048 
0049 #include <boost/parameter/aux_/void.hpp>
0050 #include <boost/parameter/aux_/yesno.hpp>
0051 #include <boost/parameter/aux_/result_of0.hpp>
0052 #include <boost/parameter/aux_/default.hpp>
0053 
0054 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
0055 #include <utility>
0056 
0057 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0058 #include <boost/mp11/integral.hpp>
0059 #include <boost/mp11/list.hpp>
0060 #include <boost/mp11/utility.hpp>
0061 #include <type_traits>
0062 #endif
0063 
0064 namespace boost { namespace parameter { namespace aux {
0065 
0066     // Terminates arg_list<> and represents an empty list.  Since this is just
0067     // the terminating case, you might want to look at arg_list first to get a
0068     // feel for what's really happening here.
0069     struct empty_arg_list
0070     {
0071         struct tagged_arg
0072         {
0073             typedef ::boost::parameter::void_ value_type;
0074         };
0075 
0076         // Variadic constructor also serves as default constructor.
0077         template <typename ...Args>
0078         inline BOOST_CONSTEXPR empty_arg_list(Args&&...)
0079         {
0080         }
0081 
0082         // A metafunction class that, given a keyword and a default type,
0083         // returns the appropriate result type for a keyword lookup given
0084         // that default.
0085         struct binding
0086         {
0087             template <typename KW, typename Default, typename Reference>
0088             struct apply
0089             {
0090                 typedef Default type;
0091             };
0092 
0093 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0094             template <typename KW, typename Default, typename Reference>
0095             using fn = Default;
0096 #endif
0097         };
0098 
0099         // Terminator for has_key, indicating that the keyword is unique.
0100         template <typename KW>
0101         static ::boost::parameter::aux::no_tag has_key(KW*);
0102 
0103         // If either of these operators are called, it means there is no
0104         // argument in the list that matches the supplied keyword.  Just
0105         // return the default value.
0106         template <typename K, typename Default>
0107         inline BOOST_CONSTEXPR Default&
0108             operator[](::boost::parameter::aux::default_<K,Default> x) const
0109         {
0110             return x.value;
0111         }
0112 
0113         template <typename K, typename Default>
0114         inline BOOST_CONSTEXPR Default&&
0115             operator[](::boost::parameter::aux::default_r_<K,Default> x) const
0116         {
0117             return ::std::forward<Default>(x.value);
0118         }
0119 
0120         // If this operator is called, it means there is no argument in the
0121         // list that matches the supplied keyword.  Just evaluate and return
0122         // the default value.
0123         template <typename K, typename F>
0124         inline BOOST_CONSTEXPR
0125         typename ::boost::parameter::aux::result_of0<F>::type
0126             operator[](BOOST_PARAMETER_lazy_default_fallback<K,F> x) const
0127         {
0128             return x.compute_default();
0129         }
0130 
0131         // No argument corresponding to ParameterRequirements::key_type
0132         // was found if we match this overload, so unless that parameter
0133         // has a default, we indicate that the actual arguments don't
0134         // match the function's requirements.
0135         template <typename ParameterRequirements, typename ArgPack>
0136         static typename ParameterRequirements::has_default
0137             satisfies(ParameterRequirements*, ArgPack*);
0138 
0139         // MPL sequence support
0140         typedef ::boost::parameter::aux::empty_arg_list type; // convenience
0141         // For dispatching to sequence intrinsics
0142         typedef ::boost::parameter::aux::arg_list_tag tag;
0143     };
0144 }}} // namespace boost::parameter::aux
0145 
0146 #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
0147 #include <boost/parameter/aux_/yesno.hpp>
0148 #include <boost/parameter/aux_/is_maybe.hpp>
0149 #include <boost/parameter/aux_/tagged_argument_fwd.hpp>
0150 #include <boost/parameter/aux_/parameter_requirements.hpp>
0151 #include <boost/parameter/aux_/augment_predicate.hpp>
0152 #include <boost/parameter/keyword_fwd.hpp>
0153 #include <boost/mpl/bool.hpp>
0154 #include <boost/mpl/if.hpp>
0155 #include <boost/mpl/eval_if.hpp>
0156 #include <boost/mpl/apply_wrap.hpp>
0157 #include <boost/mpl/assert.hpp>
0158 #include <boost/type_traits/is_same.hpp>
0159 #include <boost/core/enable_if.hpp>
0160 
0161 namespace boost { namespace parameter { namespace aux {
0162 
0163     // A tuple of tagged arguments, terminated with empty_arg_list.  Every
0164     // TaggedArg is an instance of tagged_argument<> or
0165     // tagged_argument_rref<>.
0166     template <
0167         typename TaggedArg
0168       , typename Next = ::boost::parameter::aux::empty_arg_list
0169 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0170       , typename EmitsErrors = ::boost::mp11::mp_true
0171 #else
0172       , typename EmitsErrors = ::boost::mpl::true_
0173 #endif
0174     >
0175     class arg_list : public Next
0176     {
0177 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0178         using _holds_maybe = typename ::boost::parameter::aux
0179         ::is_maybe<typename TaggedArg::value_type>::type;
0180 #else
0181         typedef typename ::boost::parameter::aux
0182         ::is_maybe<typename TaggedArg::value_type>::type _holds_maybe;
0183 #endif
0184 
0185         TaggedArg arg;      // Stores the argument
0186 
0187      public:
0188         typedef TaggedArg tagged_arg;
0189         typedef ::boost::parameter::aux::arg_list<TaggedArg,Next> self;
0190         typedef typename TaggedArg::key_type key_type;
0191 
0192 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0193         using reference = typename ::boost::mp11::mp_if<
0194             _holds_maybe
0195           , ::boost::parameter::aux
0196             ::get_reference<typename TaggedArg::value_type>
0197           , ::boost::parameter::aux::get_reference<TaggedArg>
0198         >::type;
0199 
0200         using value_type = ::boost::mp11
0201         ::mp_if<_holds_maybe,reference,typename TaggedArg::value_type>;
0202 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
0203         typedef typename ::boost::mpl::eval_if<
0204             _holds_maybe
0205           , ::boost::parameter::aux
0206             ::get_reference<typename TaggedArg::value_type>
0207           , ::boost::parameter::aux::get_reference<TaggedArg>
0208         >::type reference;
0209 
0210         typedef typename ::boost::mpl::if_<
0211             _holds_maybe
0212           , reference
0213           , typename TaggedArg::value_type
0214         >::type value_type;
0215 #endif  // BOOST_PARAMETER_CAN_USE_MP11
0216 
0217         // Create a new list by prepending arg to a copy of tail.  Used when
0218         // incrementally building this structure with the comma operator.
0219         inline BOOST_CONSTEXPR arg_list(
0220             TaggedArg const& head
0221           , Next const& tail
0222         ) : Next(tail), arg(head)
0223         {
0224         }
0225 
0226         // Store the arguments in successive nodes of this list.
0227         // Use tag dispatching to determine whether to forward all arguments
0228         // to the Next constructor, or store the first argument and forward
0229         // the rest. -- Cromwell D. Enage
0230         template <typename A0>
0231         inline BOOST_CONSTEXPR arg_list(
0232             ::boost::parameter::aux::value_type_is_not_void
0233           , A0&& a0
0234         ) : Next(
0235 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0236                 ::boost::mp11::mp_if<
0237                     ::std::is_same<
0238 #else
0239                 typename ::boost::mpl::if_<
0240                     ::boost::is_same<
0241 #endif
0242                         typename Next::tagged_arg::value_type
0243                       , ::boost::parameter::void_
0244                     >
0245                   , ::boost::parameter::aux::value_type_is_void
0246                   , ::boost::parameter::aux::value_type_is_not_void
0247 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0248                 >()
0249 #else
0250                 >::type()
0251 #endif
0252             )
0253           , arg(::std::forward<A0>(a0))
0254         {
0255         }
0256 
0257         template <typename ...Args>
0258         inline BOOST_CONSTEXPR arg_list(
0259             ::boost::parameter::aux::value_type_is_void
0260           , Args&&... args
0261         ) : Next(
0262 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0263                 ::boost::mp11::mp_if<
0264                     ::std::is_same<
0265 #else
0266                 typename ::boost::mpl::if_<
0267                     ::boost::is_same<
0268 #endif
0269                         typename Next::tagged_arg::value_type
0270                       , ::boost::parameter::void_
0271                     >
0272                   , ::boost::parameter::aux::value_type_is_void
0273                   , ::boost::parameter::aux::value_type_is_not_void
0274 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0275                 >()
0276 #else
0277                 >::type()
0278 #endif
0279               , ::std::forward<Args>(args)...
0280             )
0281           , arg(::boost::parameter::aux::void_reference())
0282         {
0283         }
0284 
0285         template <typename A0, typename A1, typename ...Args>
0286         inline BOOST_CONSTEXPR arg_list(
0287             ::boost::parameter::aux::value_type_is_not_void
0288           , A0&& a0
0289           , A1&& a1
0290           , Args&&... args
0291         ) : Next(
0292 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0293                 ::boost::mp11::mp_if<
0294                     ::std::is_same<
0295 #else
0296                 typename ::boost::mpl::if_<
0297                     ::boost::is_same<
0298 #endif
0299                         typename Next::tagged_arg::value_type
0300                       , ::boost::parameter::void_
0301                     >
0302                   , ::boost::parameter::aux::value_type_is_void
0303                   , ::boost::parameter::aux::value_type_is_not_void
0304 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0305                 >()
0306 #else
0307                 >::type()
0308 #endif
0309               , ::std::forward<A1>(a1)
0310               , ::std::forward<Args>(args)...
0311             )
0312           , arg(::std::forward<A0>(a0))
0313         {
0314         }
0315 
0316         // A metafunction class that, given a keyword and a default type,
0317         // returns the appropriate result type for a keyword lookup given
0318         // that default.
0319         struct binding
0320         {
0321             typedef typename Next::binding next_binding;
0322 
0323             template <typename KW, typename Default, typename Reference>
0324             struct apply
0325             {
0326                 typedef typename ::boost::mpl::eval_if<
0327                     ::boost::is_same<KW,key_type>
0328                   , ::boost::mpl::if_<Reference,reference,value_type>
0329                   , ::boost::mpl
0330                     ::apply_wrap3<next_binding,KW,Default,Reference>
0331                 >::type type;
0332             };
0333 
0334 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0335             template <typename KW, typename Default, typename Reference>
0336             using fn = ::boost::mp11::mp_if<
0337                 ::std::is_same<KW,key_type>
0338               , ::boost::mp11::mp_if<Reference,reference,value_type>
0339               , ::boost::mp11::mp_apply_q<
0340                     next_binding
0341                   , ::boost::mp11::mp_list<KW,Default,Reference>
0342                 >
0343             >;
0344 #endif
0345         };
0346 
0347         // Overload for key_type, so the assert below will fire
0348         // if the same keyword is used again.
0349         static ::boost::parameter::aux::yes_tag has_key(key_type*);
0350         using Next::has_key;
0351 
0352      private:
0353 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0354         using _has_unique_key = ::boost::mp11::mp_bool<
0355 #else
0356         typedef ::boost::mpl::bool_<
0357 #endif
0358             sizeof(
0359                 Next::has_key(
0360                     static_cast<key_type*>(BOOST_PARAMETER_AUX_PP_NULLPTR)
0361                 )
0362             ) == sizeof(::boost::parameter::aux::no_tag)
0363 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0364         >;
0365 #else
0366         > _has_unique_key;
0367 #endif
0368 
0369 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0370         static_assert(
0371             !(EmitsErrors::value) || (_has_unique_key::value)
0372           , "duplicate keyword"
0373         );
0374 #else
0375         BOOST_MPL_ASSERT_MSG(
0376             !(EmitsErrors::value) || (_has_unique_key::value)
0377           , duplicate_keyword
0378           , (key_type)
0379         );
0380 #endif
0381 
0382         //
0383         // Begin implementation of indexing operators
0384         // for looking up specific arguments by name.
0385         //
0386 
0387         // Helpers that handle the case when TaggedArg is empty<T>.
0388         template <typename D>
0389         inline BOOST_CONSTEXPR reference
0390 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0391             get_default(D const&, ::boost::mp11::mp_false) const
0392 #else
0393             get_default(D const&, ::boost::mpl::false_) const
0394 #endif
0395         {
0396             return this->arg.get_value();
0397         }
0398 
0399         template <typename D>
0400         inline BOOST_CONSTEXPR reference
0401 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0402             get_default(D const& d, ::boost::mp11::mp_true) const
0403 #else
0404             get_default(D const& d, ::boost::mpl::true_) const
0405 #endif
0406         {
0407             return (
0408                 this->arg.get_value()
0409               ? this->arg.get_value().get()
0410               : this->arg.get_value().construct(d.value)
0411             );
0412         }
0413 
0414      public:
0415         inline BOOST_CONSTEXPR reference
0416             operator[](::boost::parameter::keyword<key_type> const&) const
0417         {
0418 #if !defined(BOOST_NO_CXX14_CONSTEXPR)
0419 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0420             static_assert(!_holds_maybe::value, "must not hold maybe");
0421 #elif !( \
0422         BOOST_WORKAROUND(BOOST_GCC, >= 40700) && \
0423         BOOST_WORKAROUND(BOOST_GCC, < 40900) \
0424     ) && !BOOST_WORKAROUND(BOOST_GCC, >= 50000) && \
0425     !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
0426             BOOST_MPL_ASSERT_NOT((_holds_maybe));
0427 #endif
0428 #endif
0429             return this->arg.get_value();
0430         }
0431 
0432         template <typename Default>
0433         inline BOOST_CONSTEXPR reference
0434             operator[](
0435                 ::boost::parameter::aux::default_<key_type,Default> const& d
0436             ) const
0437         {
0438             return this->get_default(d, _holds_maybe());
0439         }
0440 
0441         template <typename Default>
0442         inline BOOST_CONSTEXPR reference
0443             operator[](
0444                 ::boost::parameter::aux::default_r_<key_type,Default> const& d
0445             ) const
0446         {
0447             return this->get_default(d, _holds_maybe());
0448         }
0449 
0450         template <typename Default>
0451         inline BOOST_CONSTEXPR reference
0452             operator[](
0453                 BOOST_PARAMETER_lazy_default_fallback<key_type,Default> const&
0454             ) const
0455         {
0456 #if !defined(BOOST_NO_CXX14_CONSTEXPR)
0457 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0458             static_assert(!_holds_maybe::value, "must not hold maybe");
0459 #elif !( \
0460         BOOST_WORKAROUND(BOOST_GCC, >= 40700) && \
0461         BOOST_WORKAROUND(BOOST_GCC, < 40900) \
0462     ) && !BOOST_WORKAROUND(BOOST_GCC, >= 50000) && \
0463     !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
0464             BOOST_MPL_ASSERT_NOT((_holds_maybe));
0465 #endif
0466 #endif
0467             return this->arg.get_value();
0468         }
0469 
0470         // Builds an overload set including operator[]s defined
0471         // in base classes.
0472         using Next::operator[];
0473 
0474         //
0475         // End of indexing support
0476         //
0477 
0478         // For parameter_requirements matching this node's key_type, return
0479         // a bool constant wrapper indicating whether the requirements are
0480         // satisfied by TaggedArg.  Used only for compile-time computation
0481         // and never really called, so a declaration is enough.
0482         template <typename HasDefault, typename Predicate, typename ArgPack>
0483         static typename ::boost::lazy_enable_if<
0484 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
0485             ::boost::mp11::mp_if<
0486                 EmitsErrors
0487               , ::boost::mp11::mp_true
0488               , _has_unique_key
0489             >
0490           , ::boost::parameter::aux::augment_predicate_mp11<
0491 #else
0492             typename ::boost::mpl::if_<
0493                 EmitsErrors
0494               , ::boost::mpl::true_
0495               , _has_unique_key
0496             >::type
0497           , ::boost::parameter::aux::augment_predicate<
0498 #endif
0499                 Predicate
0500               , reference
0501               , key_type
0502               , value_type
0503               , ArgPack
0504             >
0505         >::type
0506             satisfies(
0507                 ::boost::parameter::aux::parameter_requirements<
0508                     key_type
0509                   , Predicate
0510                   , HasDefault
0511                 >*
0512               , ArgPack*
0513             );
0514 
0515         // Builds an overload set including satisfies functions defined
0516         // in base classes.
0517         using Next::satisfies;
0518 
0519         // Comma operator to compose argument list without using parameters<>.
0520         // Useful for argument lists with undetermined length.
0521         template <typename KW, typename T2>
0522         inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
0523             ::boost::parameter::aux::tagged_argument<KW,T2>
0524           , self
0525         >
0526             operator,(
0527                 ::boost::parameter::aux::tagged_argument<KW,T2> const& x
0528             ) const
0529         {
0530             return ::boost::parameter::aux::arg_list<
0531                 ::boost::parameter::aux::tagged_argument<KW,T2>
0532               , self
0533             >(x, *this);
0534         }
0535 
0536         template <typename KW, typename T2>
0537         inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
0538             ::boost::parameter::aux::tagged_argument_rref<KW,T2>
0539           , self
0540         >
0541             operator,(
0542                 ::boost::parameter::aux::tagged_argument_rref<KW,T2> const& x
0543             ) const
0544         {
0545             return ::boost::parameter::aux::arg_list<
0546                 ::boost::parameter::aux::tagged_argument_rref<KW,T2>
0547               , self
0548             >(x, *this);
0549         }
0550 
0551         // MPL sequence support
0552         typedef self type;        // Convenience for users
0553         typedef Next tail_type;   // For the benefit of iterators
0554         // For dispatching to sequence intrinsics
0555         typedef ::boost::parameter::aux::arg_list_tag tag;
0556     };
0557 }}} // namespace boost::parameter::aux
0558 
0559 #else   // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
0560 
0561 #include <boost/preprocessor/repetition/enum_params.hpp>
0562 #include <boost/preprocessor/facilities/intercept.hpp>
0563 
0564 namespace boost { namespace parameter { namespace aux {
0565 
0566     // Terminates arg_list<> and represents an empty list.  Since this is just
0567     // the terminating case, you might want to look at arg_list first to get a
0568     // feel for what's really happening here.
0569     struct empty_arg_list
0570     {
0571         inline BOOST_CONSTEXPR empty_arg_list()
0572         {
0573         }
0574 
0575         // Constructor taking BOOST_PARAMETER_COMPOSE_MAX_ARITY empty_arg_list
0576         // arguments; this makes initialization.
0577         inline BOOST_CONSTEXPR empty_arg_list(
0578             BOOST_PP_ENUM_PARAMS(
0579                 BOOST_PARAMETER_COMPOSE_MAX_ARITY
0580               , ::boost::parameter::void_ BOOST_PP_INTERCEPT
0581             )
0582         )
0583         {
0584         }
0585 
0586         // A metafunction class that, given a keyword and a default type,
0587         // returns the appropriate result type for a keyword lookup given
0588         // that default.
0589         struct binding
0590         {
0591             template <typename KW, typename Default, typename Reference>
0592             struct apply
0593             {
0594                 typedef Default type;
0595             };
0596         };
0597 
0598         // Terminator for has_key, indicating that the keyword is unique.
0599         template <typename KW>
0600         static ::boost::parameter::aux::no_tag has_key(KW*);
0601 
0602 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
0603         // The overload set technique doesn't work with these older compilers,
0604         // so they need some explicit handholding.
0605 
0606         // A metafunction class that, given a keyword, returns the type of the
0607         // base sublist whose get() function can produce the value for that key.
0608         struct key_owner
0609         {
0610             template <typename KW>
0611             struct apply
0612             {
0613                 typedef ::boost::parameter::aux::empty_arg_list type;
0614             };
0615         };
0616 #endif  // Borland workarounds needed
0617 
0618         // If either of these operators are called, it means there is no
0619         // argument in the list that matches the supplied keyword.  Just
0620         // return the default value.
0621         template <typename K, typename Default>
0622         inline BOOST_CONSTEXPR Default&
0623             operator[](::boost::parameter::aux::default_<K,Default> x) const
0624         {
0625             return x.value;
0626         }
0627 
0628         // If this operator is called, it means there is no argument in the
0629         // list that matches the supplied keyword.  Just evaluate and return
0630         // the default value.
0631         template <typename K, typename F>
0632         inline BOOST_CONSTEXPR
0633         typename ::boost::parameter::aux::result_of0<F>::type
0634             operator[](BOOST_PARAMETER_lazy_default_fallback<K,F> x) const
0635         {
0636             return x.compute_default();
0637         }
0638 
0639         // No argument corresponding to ParameterRequirements::key_type
0640         // was found if we match this overload, so unless that parameter
0641         // has a default, we indicate that the actual arguments don't
0642         // match the function's requirements.
0643         template <typename ParameterRequirements, typename ArgPack>
0644         static typename ParameterRequirements::has_default
0645             satisfies(ParameterRequirements*, ArgPack*);
0646 
0647         // MPL sequence support
0648         typedef ::boost::parameter::aux::empty_arg_list type; // convenience
0649         // For dispatching to sequence intrinsics
0650         typedef ::boost::parameter::aux::arg_list_tag tag;
0651     };
0652 }}} // namespace boost::parameter::aux
0653 
0654 #include <boost/parameter/aux_/yesno.hpp>
0655 #include <boost/parameter/aux_/is_maybe.hpp>
0656 #include <boost/parameter/aux_/tagged_argument_fwd.hpp>
0657 #include <boost/parameter/aux_/parameter_requirements.hpp>
0658 #include <boost/parameter/aux_/augment_predicate.hpp>
0659 #include <boost/parameter/keyword_fwd.hpp>
0660 #include <boost/mpl/bool.hpp>
0661 #include <boost/mpl/if.hpp>
0662 #include <boost/mpl/eval_if.hpp>
0663 #include <boost/mpl/apply_wrap.hpp>
0664 #include <boost/mpl/assert.hpp>
0665 #include <boost/type_traits/is_same.hpp>
0666 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
0667 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
0668 
0669 #if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
0670 #include <boost/core/enable_if.hpp>
0671 #endif
0672 
0673 #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
0674 #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
0675 #endif
0676 
0677 namespace boost { namespace parameter { namespace aux {
0678 
0679     // A tuple of tagged arguments, terminated with empty_arg_list.  Every
0680     // TaggedArg is an instance of tagged_argument<>.
0681     template <
0682         typename TaggedArg
0683       , typename Next = ::boost::parameter::aux::empty_arg_list
0684       , typename EmitsErrors = ::boost::mpl::true_
0685     >
0686     class arg_list : public Next
0687     {
0688         typedef typename ::boost::parameter::aux
0689         ::is_maybe<typename TaggedArg::value_type>::type _holds_maybe;
0690 
0691         TaggedArg arg;      // Stores the argument
0692 
0693      public:
0694         typedef TaggedArg tagged_arg;
0695         typedef ::boost::parameter::aux::arg_list<TaggedArg,Next> self;
0696         typedef typename TaggedArg::key_type key_type;
0697 
0698         typedef typename ::boost::mpl::eval_if<
0699             _holds_maybe
0700           , ::boost::parameter::aux
0701             ::get_reference<typename TaggedArg::value_type>
0702           , ::boost::parameter::aux::get_reference<TaggedArg>
0703         >::type reference;
0704 
0705         typedef typename ::boost::mpl::if_<
0706             _holds_maybe
0707           , reference
0708           , typename TaggedArg::value_type
0709         >::type value_type;
0710 
0711         // Create a new list by prepending arg to a copy of tail.  Used when
0712         // incrementally building this structure with the comma operator.
0713         inline BOOST_CONSTEXPR arg_list(
0714             TaggedArg const& head
0715           , Next const& tail
0716         ) : Next(tail), arg(head)
0717         {
0718         }
0719 
0720         // Store the arguments in successive nodes of this list.
0721         template <
0722             // typename A0, typename A1, ...
0723             BOOST_PP_ENUM_PARAMS(
0724                 BOOST_PARAMETER_COMPOSE_MAX_ARITY
0725               , typename A
0726             )
0727         >
0728         inline BOOST_CONSTEXPR arg_list(
0729             // A0& a0, A1& a1, ...
0730             BOOST_PP_ENUM_BINARY_PARAMS(
0731                 BOOST_PARAMETER_COMPOSE_MAX_ARITY
0732               , A
0733               , & a
0734             )
0735         ) : Next(
0736                 // a1, a2, ...
0737                 BOOST_PP_ENUM_SHIFTED_PARAMS(
0738                     BOOST_PARAMETER_COMPOSE_MAX_ARITY
0739                   , a
0740                 )
0741               , ::boost::parameter::aux::void_reference()
0742             )
0743           , arg(a0)
0744         {
0745         }
0746 
0747         // A metafunction class that, given a keyword and a default type,
0748         // returns the appropriate result type for a keyword lookup given
0749         // that default.
0750         struct binding
0751         {
0752             typedef typename Next::binding next_binding;
0753 
0754             template <typename KW, typename Default, typename Reference>
0755             struct apply
0756             {
0757                 typedef typename ::boost::mpl::eval_if<
0758                     ::boost::is_same<KW,key_type>
0759                   , ::boost::mpl::if_<Reference,reference,value_type>
0760                   , ::boost::mpl::apply_wrap3<
0761                         next_binding
0762                       , KW
0763                       , Default
0764                       , Reference
0765                     >
0766                 >::type type;
0767             };
0768         };
0769 
0770 #if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
0771         // Overload for key_type, so the assert below will fire
0772         // if the same keyword is used again.
0773         static ::boost::parameter::aux::yes_tag has_key(key_type*);
0774         using Next::has_key;
0775 
0776      private:
0777 #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(BOOST_MSVC, < 1800)
0778         BOOST_MPL_ASSERT_MSG(
0779             sizeof(
0780                 Next::has_key(
0781                     static_cast<key_type*>(BOOST_PARAMETER_AUX_PP_NULLPTR)
0782                 )
0783             ) == sizeof(::boost::parameter::aux::no_tag)
0784           , duplicate_keyword
0785           , (key_type)
0786         );
0787 #else
0788         typedef ::boost::mpl::bool_<
0789             sizeof(
0790                 Next::has_key(
0791                     static_cast<key_type*>(BOOST_PARAMETER_AUX_PP_NULLPTR)
0792                 )
0793             ) == sizeof(::boost::parameter::aux::no_tag)
0794         > _has_unique_key;
0795 
0796         BOOST_MPL_ASSERT_MSG(
0797             !(EmitsErrors::value) || (_has_unique_key::value)
0798           , duplicate_keyword
0799           , (key_type)
0800         );
0801 #endif  // SFINAE/MSVC workarounds needed
0802 #endif  // Borland workarounds not needed
0803 
0804      private:
0805         //
0806         // Begin implementation of indexing operators
0807         // for looking up specific arguments by name.
0808         //
0809 
0810         // Helpers that handle the case when TaggedArg is empty<T>.
0811         template <typename D>
0812         inline BOOST_CONSTEXPR reference
0813             get_default(D const&, ::boost::mpl::false_) const
0814         {
0815             return this->arg.get_value();
0816         }
0817 
0818         template <typename D>
0819         inline BOOST_CONSTEXPR reference
0820             get_default(D const& d, ::boost::mpl::true_) const
0821         {
0822             return (
0823                 this->arg.get_value()
0824               ? this->arg.get_value().get()
0825               : this->arg.get_value().construct(d.value)
0826             );
0827         }
0828 
0829      public:
0830 #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
0831         // These older compilers don't support the overload set creation
0832         // idiom well, so we need to do all the return type calculation
0833         // for the compiler and dispatch through an outer function template.
0834 
0835         // A metafunction class that, given a keyword, returns the base
0836         // sublist whose get() function can produce the value for that key.
0837         struct key_owner
0838         {
0839             typedef typename Next::key_owner next_key_owner;
0840 
0841             template <typename KW>
0842             struct apply
0843             {
0844                 typedef typename ::boost::mpl::eval_if<
0845                     ::boost::is_same<KW,key_type>
0846                   , ::boost::mpl::identity<
0847                         ::boost::parameter::aux::arg_list<TaggedArg,Next>
0848                     >
0849                   , ::boost::mpl::apply_wrap1<next_key_owner,KW>
0850                 >::type type;
0851             };
0852         };
0853 
0854         // Outer indexing operators that dispatch to the right node's
0855         // get() function.
0856         template <typename KW>
0857         inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
0858             binding
0859           , KW
0860           , ::boost::parameter::void_
0861           , ::boost::mpl::true_
0862         >::type
0863             operator[](::boost::parameter::keyword<KW> const& x) const
0864         {
0865             typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const&
0866                 sublist = *this;
0867             return sublist.get(x);
0868         }
0869 
0870         template <typename KW, typename Default>
0871         inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
0872             binding
0873           , KW
0874           , Default&
0875           , ::boost::mpl::true_
0876         >::type
0877             operator[](
0878                 ::boost::parameter::aux::default_<KW,Default> const& x
0879             ) const
0880         {
0881             typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const&
0882                 sublist = *this;
0883             return sublist.get(x);
0884         }
0885 
0886         template <typename KW, typename F>
0887         inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
0888             binding
0889           , KW
0890           , typename ::boost::parameter::aux::result_of0<F>::type
0891           , ::boost::mpl::true_
0892         >::type
0893             operator[](
0894                 BOOST_PARAMETER_lazy_default_fallback<KW,F> const& x
0895             ) const
0896         {
0897             typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const&
0898                 sublist = *this;
0899             return sublist.get(x);
0900         }
0901 
0902         // These just return the stored value; when empty_arg_list is reached,
0903         // indicating no matching argument was passed, the default is
0904         // returned, or if no default_ or lazy_default was passed, compilation
0905         // fails.
0906         inline BOOST_CONSTEXPR reference
0907             get(::boost::parameter::keyword<key_type> const&) const
0908         {
0909             BOOST_MPL_ASSERT_NOT((_holds_maybe));
0910             return this->arg.get_value();
0911         }
0912 
0913         template <typename Default>
0914         inline BOOST_CONSTEXPR reference
0915             get(
0916                 ::boost::parameter::aux::default_<key_type,Default> const& d
0917             ) const
0918         {
0919             return this->get_default(d, _holds_maybe());
0920         }
0921 
0922         template <typename Default>
0923         inline BOOST_CONSTEXPR reference
0924             get(
0925                 BOOST_PARAMETER_lazy_default_fallback<key_type,Default> const&
0926             ) const
0927         {
0928             return this->arg.get_value();
0929         }
0930 #else   // !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
0931         inline BOOST_CONSTEXPR reference
0932             operator[](::boost::parameter::keyword<key_type> const&) const
0933         {
0934             BOOST_MPL_ASSERT_NOT((_holds_maybe));
0935             return this->arg.get_value();
0936         }
0937 
0938         template <typename Default>
0939         inline BOOST_CONSTEXPR reference
0940             operator[](
0941                 ::boost::parameter::aux::default_<key_type,Default> const& d
0942             ) const
0943         {
0944             return this->get_default(d, _holds_maybe());
0945         }
0946 
0947         template <typename Default>
0948         inline BOOST_CONSTEXPR reference
0949             operator[](
0950                 BOOST_PARAMETER_lazy_default_fallback<key_type,Default> const&
0951             ) const
0952         {
0953             BOOST_MPL_ASSERT_NOT((_holds_maybe));
0954             return this->arg.get_value();
0955         }
0956 
0957         // Builds an overload set including operator[]s defined
0958         // in base classes.
0959         using Next::operator[];
0960 
0961         //
0962         // End of indexing support
0963         //
0964 
0965         // For parameter_requirements matching this node's key_type, return
0966         // a bool constant wrapper indicating whether the requirements are
0967         // satisfied by TaggedArg.  Used only for compile-time computation
0968         // and never really called, so a declaration is enough.
0969         template <typename HasDefault, typename Predicate, typename ArgPack>
0970         static typename
0971 #if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
0972         ::boost::lazy_enable_if<
0973             typename ::boost::mpl::if_<
0974                 EmitsErrors
0975               , ::boost::mpl::true_
0976               , _has_unique_key
0977             >::type,
0978 #endif
0979             ::boost::parameter::aux::augment_predicate<
0980                 Predicate
0981               , reference
0982               , key_type
0983               , value_type
0984               , ArgPack
0985 #if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
0986            >
0987 #endif
0988         >::type
0989             satisfies(
0990                 ::boost::parameter::aux::parameter_requirements<
0991                     key_type
0992                   , Predicate
0993                   , HasDefault
0994                 >*
0995               , ArgPack*
0996             );
0997 
0998         // Builds an overload set including satisfies functions defined
0999         // in base classes.
1000         using Next::satisfies;
1001 #endif  // Borland workarounds needed
1002 
1003         // Comma operator to compose argument list without using parameters<>.
1004         // Useful for argument lists with undetermined length.
1005         template <typename KW, typename T2>
1006         inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
1007             ::boost::parameter::aux::tagged_argument<KW,T2>
1008           , self
1009         >
1010             operator,(
1011                 ::boost::parameter::aux::tagged_argument<KW,T2> const& x
1012             ) const
1013         {
1014             return ::boost::parameter::aux::arg_list<
1015                 ::boost::parameter::aux::tagged_argument<KW,T2>
1016               , self
1017             >(x, *this);
1018         }
1019 
1020         // MPL sequence support
1021         typedef self type;        // Convenience for users
1022         typedef Next tail_type;   // For the benefit of iterators
1023         // For dispatching to sequence intrinsics
1024         typedef ::boost::parameter::aux::arg_list_tag tag;
1025     };
1026 }}} // namespace boost::parameter::aux
1027 
1028 #endif  // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
1029 
1030 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
1031 
1032 namespace boost { namespace parameter { namespace aux {
1033 
1034     template <typename ...ArgTuples>
1035     struct arg_list_cons;
1036 
1037     template <>
1038     struct arg_list_cons<>
1039     {
1040         using type = ::boost::parameter::aux::empty_arg_list;
1041     };
1042 
1043     template <typename ArgTuple0, typename ...Tuples>
1044     struct arg_list_cons<ArgTuple0,Tuples...>
1045     {
1046         using type = ::boost::parameter::aux::arg_list<
1047             typename ArgTuple0::tagged_arg
1048           , typename ::boost::parameter::aux::arg_list_cons<Tuples...>::type
1049           , typename ArgTuple0::emits_errors
1050         >;
1051     };
1052 
1053     template <
1054         typename Keyword
1055       , typename TaggedArg
1056       , typename EmitsErrors = ::boost::mp11::mp_true
1057     >
1058     struct flat_like_arg_tuple
1059     {
1060         using tagged_arg = TaggedArg;
1061         using emits_errors = EmitsErrors;
1062     };
1063 
1064     template <typename ...ArgTuples>
1065     class flat_like_arg_list
1066       : public ::boost::parameter::aux::arg_list_cons<ArgTuples...>::type
1067     {
1068         using _base_type = typename ::boost::parameter::aux
1069         ::arg_list_cons<ArgTuples...>::type;
1070 
1071      public:
1072         inline BOOST_CONSTEXPR flat_like_arg_list(
1073             typename _base_type::tagged_arg const& head
1074           , typename _base_type::tail_type const& tail
1075         ) : _base_type(head, tail)
1076         {
1077         }
1078 
1079         template <typename ...Args>
1080         inline BOOST_CONSTEXPR flat_like_arg_list(Args&&... args)
1081           : _base_type(::std::forward<Args>(args)...)
1082         {
1083         }
1084 
1085         using _base_type::operator[];
1086         using _base_type::satisfies;
1087 
1088         // Comma operator to compose argument list without using parameters<>.
1089         // Useful for argument lists with undetermined length.
1090         template <typename TaggedArg>
1091         inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list<
1092             ::boost::parameter::aux::flat_like_arg_tuple<
1093                 typename TaggedArg::base_type::key_type
1094               , typename TaggedArg::base_type
1095             >
1096           , ArgTuples...
1097         >
1098             operator,(TaggedArg const& x) const
1099         {
1100             return ::boost::parameter::aux::flat_like_arg_list<
1101                 ::boost::parameter::aux::flat_like_arg_tuple<
1102                     typename TaggedArg::base_type::key_type
1103                   , typename TaggedArg::base_type
1104                 >
1105               , ArgTuples...
1106             >(
1107                 static_cast<typename TaggedArg::base_type const&>(x)
1108               , static_cast<_base_type const&>(*this)
1109             );
1110         }
1111     };
1112 
1113     template <>
1114     class flat_like_arg_list<>
1115       : public ::boost::parameter::aux::empty_arg_list
1116     {
1117         using _base_type = ::boost::parameter::aux::empty_arg_list;
1118 
1119      public:
1120         template <typename ...Args>
1121         inline BOOST_CONSTEXPR flat_like_arg_list(Args&&... args)
1122           : _base_type(::std::forward<Args>(args)...)
1123         {
1124         }
1125 
1126         using _base_type::operator[];
1127         using _base_type::satisfies;
1128 
1129         // Comma operator to compose argument list without using parameters<>.
1130         // Useful for argument lists with undetermined length.
1131         template <typename TaggedArg>
1132         inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list<
1133             ::boost::parameter::aux::flat_like_arg_tuple<
1134                 typename TaggedArg::base_type::key_type
1135               , typename TaggedArg::base_type
1136             >
1137         >
1138             operator,(TaggedArg const& x) const
1139         {
1140             return ::boost::parameter::aux::flat_like_arg_list<
1141                 ::boost::parameter::aux::flat_like_arg_tuple<
1142                     typename TaggedArg::base_type::key_type
1143                   , typename TaggedArg::base_type
1144                 >
1145             >(
1146                 static_cast<typename TaggedArg::base_type const&>(x)
1147               , static_cast<_base_type const&>(*this)
1148             );
1149         }
1150     };
1151 }}} // namespace boost::parameter::aux
1152 
1153 #endif  // BOOST_PARAMETER_CAN_USE_MP11
1154 
1155 #include <boost/mpl/iterator_tags.hpp>
1156 
1157 namespace boost { namespace parameter { namespace aux {
1158 
1159     // MPL sequence support
1160     template <typename ArgumentPack>
1161     struct arg_list_iterator
1162     {
1163         typedef ::boost::mpl::forward_iterator_tag category;
1164 
1165         // The incremented iterator
1166         typedef ::boost::parameter::aux
1167         ::arg_list_iterator<typename ArgumentPack::tail_type> next;
1168 
1169         // dereferencing yields the key type
1170         typedef typename ArgumentPack::key_type type;
1171     };
1172 
1173     template <>
1174     struct arg_list_iterator< ::boost::parameter::aux::empty_arg_list>
1175     {
1176     };
1177 }}} // namespace boost::parameter::aux
1178 
1179 #include <boost/mpl/begin_end_fwd.hpp>
1180 
1181 // MPL sequence support
1182 namespace boost { namespace mpl {
1183 
1184     template <>
1185     struct begin_impl< ::boost::parameter::aux::arg_list_tag>
1186     {
1187         template <typename S>
1188         struct apply
1189         {
1190             typedef ::boost::parameter::aux::arg_list_iterator<S> type;
1191         };
1192     };
1193 
1194     template <>
1195     struct end_impl< ::boost::parameter::aux::arg_list_tag>
1196     {
1197         template <typename>
1198         struct apply
1199         {
1200             typedef ::boost::parameter::aux::arg_list_iterator<
1201                 ::boost::parameter::aux::empty_arg_list
1202             > type;
1203         };
1204     };
1205 }} // namespace boost::mpl
1206 
1207 #include <boost/parameter/value_type.hpp>
1208 #include <boost/mpl/has_key_fwd.hpp>
1209 #include <boost/type_traits/is_void.hpp>
1210 
1211 namespace boost { namespace mpl {
1212 
1213     template <>
1214     struct has_key_impl< ::boost::parameter::aux::arg_list_tag>
1215     {
1216         template <typename ArgList, typename Keyword>
1217         struct apply
1218         {
1219             typedef typename ::boost::mpl::if_<
1220                 ::boost::is_void<
1221                     typename ::boost::parameter
1222                     ::value_type<ArgList,Keyword,void>::type
1223                 >
1224               , ::boost::mpl::false_
1225               , ::boost::mpl::true_
1226             >::type type;
1227         };
1228     };
1229 }} // namespace boost::mpl
1230 
1231 #include <boost/mpl/count_fwd.hpp>
1232 #include <boost/mpl/int.hpp>
1233 
1234 namespace boost { namespace mpl {
1235 
1236     template <>
1237     struct count_impl< ::boost::parameter::aux::arg_list_tag>
1238     {
1239         template <typename ArgList, typename Keyword>
1240         struct apply
1241         {
1242             typedef typename ::boost::mpl::if_<
1243                 ::boost::is_void<
1244                     typename ::boost::parameter
1245                     ::value_type<ArgList,Keyword,void>::type
1246                 >
1247               , ::boost::mpl::int_<0>
1248               , ::boost::mpl::int_<1>
1249             >::type type;
1250         };
1251     };
1252 }} // namespace boost::mpl
1253 
1254 #include <boost/mpl/key_type_fwd.hpp>
1255 #include <boost/mpl/identity.hpp>
1256 
1257 namespace boost { namespace mpl {
1258 
1259     template <>
1260     struct key_type_impl< ::boost::parameter::aux::arg_list_tag>
1261     {
1262         template <typename ArgList, typename Keyword>
1263         struct apply
1264         {
1265             typedef typename ::boost::mpl::eval_if<
1266                 ::boost::is_void<
1267                     typename ::boost::parameter
1268                     ::value_type<ArgList,Keyword,void>::type
1269                 >
1270               , void
1271               , ::boost::mpl::identity<Keyword>
1272             >::type type;
1273         };
1274     };
1275 }} // namespace boost::mpl
1276 
1277 #include <boost/mpl/value_type_fwd.hpp>
1278 
1279 namespace boost { namespace mpl {
1280 
1281     template <>
1282     struct value_type_impl< ::boost::parameter::aux::arg_list_tag>
1283       : ::boost::mpl::key_type_impl< ::boost::parameter::aux::arg_list_tag>
1284     {
1285     };
1286 }} // namespace boost::mpl
1287 
1288 #include <boost/mpl/at_fwd.hpp>
1289 
1290 namespace boost { namespace mpl {
1291 
1292     template <>
1293     struct at_impl< ::boost::parameter::aux::arg_list_tag>
1294       : ::boost::mpl::key_type_impl< ::boost::parameter::aux::arg_list_tag>
1295     {
1296     };
1297 }} // namespace boost::mpl
1298 
1299 #include <boost/mpl/order_fwd.hpp>
1300 #include <boost/mpl/void.hpp>
1301 #include <boost/mpl/find.hpp>
1302 #include <boost/mpl/distance.hpp>
1303 
1304 namespace boost { namespace mpl {
1305 
1306     template <>
1307     struct order_impl< ::boost::parameter::aux::arg_list_tag>
1308     {
1309         template <typename ArgList, typename Keyword>
1310         struct apply
1311         {
1312             typedef typename ::boost::mpl::find<ArgList,Keyword>::type Itr;
1313             typedef typename ::boost::mpl::eval_if<
1314                 ::boost::is_void<
1315                     typename ::boost::parameter
1316                     ::value_type<ArgList,Keyword,void>::type
1317                 >
1318               , ::boost::mpl::identity< ::boost::mpl::void_>
1319               , ::boost::mpl::distance<
1320                     Itr
1321                   , ::boost::parameter::aux::arg_list_iterator<
1322                         ::boost::parameter::aux::empty_arg_list
1323                     >
1324                 >
1325             >::type type;
1326         };
1327     };
1328 }} // namespace boost::mpl
1329 
1330 #endif  // include guard
1331