BVB Source Codes

mars Show arg_list.hpp Source code

Return Download mars: download arg_list.hpp Source code - Download mars Source code - Type:.hpp
  1. // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and
  2. // distribution is subject to the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5.  
  6. #ifndef ARG_LIST_050329_HPP
  7. #define ARG_LIST_050329_HPP
  8.  
  9. #include <boost/parameter/aux_/void.hpp>
  10. #include <boost/parameter/aux_/result_of0.hpp>
  11. #include <boost/parameter/aux_/default.hpp>
  12. #include <boost/parameter/aux_/parameter_requirements.hpp>
  13. #include <boost/parameter/aux_/yesno.hpp>
  14. #include <boost/parameter/aux_/is_maybe.hpp>
  15. #include <boost/parameter/config.hpp>
  16.  
  17. #include <boost/mpl/apply.hpp>
  18. #include <boost/mpl/assert.hpp>
  19. #include <boost/mpl/begin.hpp>
  20. #include <boost/mpl/end.hpp>
  21. #include <boost/mpl/iterator_tags.hpp>
  22.  
  23. #include <boost/type_traits/add_reference.hpp>
  24. #include <boost/type_traits/is_same.hpp>
  25. #include <boost/preprocessor/repetition/enum_params.hpp>
  26. #include <boost/preprocessor/repetition/enum_binary_params.hpp>
  27. #include <boost/preprocessor/facilities/intercept.hpp>
  28.  
  29. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost { namespace parameter {
  30.  
  31. // Forward declaration for aux::arg_list, below.
  32. template<class T> struct keyword;
  33.  
  34. namespace aux {
  35.  
  36. // Tag type passed to MPL lambda.
  37. struct lambda_tag;
  38.  
  39. //
  40. // Structures used to build the tuple of actual arguments.  The
  41. // tuple is a nested cons-style list of arg_list specializations
  42. // terminated by an empty_arg_list.
  43. //
  44. // Each specialization of arg_list is derived from its successor in
  45. // the list type.  This feature is used along with using
  46. // declarations to build member function overload sets that can
  47. // match against keywords.
  48. //
  49.  
  50. // MPL sequence support
  51. struct arg_list_tag;
  52.  
  53. // Terminates arg_list<> and represents an empty list.  Since this
  54. // is just the terminating case you might want to look at arg_list
  55. // first, to get a feel for what's really happening here.
  56.  
  57. struct empty_arg_list
  58. {
  59.     empty_arg_list() {}
  60.  
  61.     // Constructor taking BOOST_PARAMETER_MAX_ARITY empty_arg_list
  62.     // arguments; this makes initialization
  63.     empty_arg_list(
  64.         BOOST_PP_ENUM_PARAMS(
  65.             BOOST_PARAMETER_MAX_ARITY, void_ BOOST_PP_INTERCEPT
  66.         ))
  67.     {}
  68.  
  69.     // A metafunction class that, given a keyword and a default
  70.     // type, returns the appropriate result type for a keyword
  71.     // lookup given that default
  72.     struct binding
  73.     {
  74.         template<class KW, class Default, class Reference>
  75.         struct apply
  76.         {
  77.             typedef Default type;
  78.         };
  79.     };
  80.  
  81.     // Terminator for has_key, indicating that the keyword is unique
  82.     template <class KW>
  83.     static no_tag has_key(KW*);
  84.  
  85. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  86.  
  87.     // The overload set technique doesn't work with these older
  88.     // compilers, so they need some explicit handholding.
  89.  
  90.     // A metafunction class that, given a keyword, returns the type
  91.     // of the base sublist whose get() function can produce the
  92.     // value for that key
  93.     struct key_owner
  94.     {
  95.         template<class KW>
  96.         struct apply
  97.         {
  98.             typedef empty_arg_list type;
  99.         };
  100.     };
  101.  
  102.     template <class K, class T>
  103.     T& get(default_<K,T> x) const
  104.     {
  105.         return x.value;
  106.     }
  107.  
  108.     template <class K, class F>
  109.     typename result_of0<F>::type
  110.     get(lazy_default<K,F> x) const
  111.     {
  112.         return x.compute_default();
  113.     }
  114. #endif
  115.  
  116.     // If this function is called, it means there is no argument
  117.     // in the list that matches the supplied keyword. Just return
  118.     // the default value.
  119.     template <class K, class Default>
  120.     Default& operator[](default_<K, Default> x) const
  121.     {
  122.         return x.value;
  123.     }
  124.  
  125.     // If this function is called, it means there is no argument
  126.     // in the list that matches the supplied keyword. Just evaluate
  127.     // and return the default value.
  128.     template <class K, class F>
  129.     typename result_of0<F>::type
  130.     operator[](
  131.         BOOST_PARAMETER_lazy_default_fallback<K,F> x) const
  132.     {
  133.         return x.compute_default();
  134.     }
  135.  
  136.     // No argument corresponding to ParameterRequirements::key_type
  137.     // was found if we match this overload, so unless that parameter
  138.     // has a default, we indicate that the actual arguments don't
  139.     // match the function's requirements.
  140.     template <class ParameterRequirements, class ArgPack>
  141.     static typename ParameterRequirements::has_default
  142.     satisfies(ParameterRequirements*, ArgPack*);
  143.  
  144.     // MPL sequence support
  145.     typedef empty_arg_list type;   // convenience
  146.     typedef arg_list_tag tag; // For dispatching to sequence intrinsics
  147. };
  148.  
  149. // Forward declaration for arg_list::operator,
  150. template <class KW, class T>
  151. struct tagged_argument;
  152.  
  153. template <class T>
  154. struct get_reference
  155. {
  156.     typedef typename T::reference type;
  157. };
  158.  
  159. // A tuple of tagged arguments, terminated with empty_arg_list.
  160. // Every TaggedArg is an instance of tagged_argument<>.
  161. template <class TaggedArg, class Next = empty_arg_list>
  162. struct arg_list : Next
  163. {
  164.     typedef arg_list<TaggedArg,Next> self;
  165.     typedef typename TaggedArg::key_type key_type;
  166.  
  167.     typedef typename is_maybe<typename TaggedArg::value_type>::type holds_maybe;
  168.  
  169.     typedef typename mpl::eval_if<
  170.         holds_maybe
  171.       , get_reference<typename TaggedArg::value_type>
  172.       , get_reference<TaggedArg>
  173.     >::type reference;
  174.  
  175.     typedef typename mpl::if_<
  176.         holds_maybe
  177.       , reference
  178.       , typename TaggedArg::value_type
  179.     >::type value_type;
  180.  
  181.     TaggedArg arg;      // Stores the argument
  182.  
  183.     // Store the arguments in successive nodes of this list
  184.     template< // class A0, class A1, ...
  185.         BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
  186.     >
  187.     arg_list( // A0& a0, A1& a1, ...
  188.         BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PARAMETER_MAX_ARITY, A, & a)
  189.     )
  190.       : Next( // a1, a2, ...
  191.             BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PARAMETER_MAX_ARITY, a)
  192.           , void_reference()
  193.         )
  194.       , arg(a0)
  195.     {}
  196.  
  197.     // Create a new list by prepending arg to a copy of tail.  Used
  198.     // when incrementally building this structure with the comma
  199.     // operator.
  200.     arg_list(TaggedArg head, Next const& tail)
  201.       : Next(tail)
  202.       , arg(head)
  203.     {}
  204.  
  205.     // A metafunction class that, given a keyword and a default
  206.     // type, returns the appropriate result type for a keyword
  207.     // lookup given that default
  208.     struct binding
  209.     {
  210.         template <class KW, class Default, class Reference>
  211.         struct apply
  212.         {
  213.           typedef typename mpl::eval_if<
  214.                 mars_boost::is_same<KW, key_type>
  215.               , mpl::if_<Reference, reference, value_type>
  216.               , mpl::apply_wrap3<typename Next::binding, KW, Default, Reference>
  217.           >::type type;
  218.         };
  219.     };
  220.  
  221. #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  222.     // Overload for key_type, so the assert below will fire if the
  223.     // same keyword is used again
  224.     static yes_tag has_key(key_type*);
  225.     using Next::has_key;
  226.  
  227.     BOOST_MPL_ASSERT_MSG(
  228.         sizeof(Next::has_key((key_type*)0)) == sizeof(no_tag)
  229.       , duplicate_keyword, (key_type)
  230.     );
  231.  
  232. #endif
  233.     //
  234.     // Begin implementation of indexing operators for looking up
  235.     // specific arguments by name
  236.     //
  237.  
  238.     // Helpers that handle the case when TaggedArg is
  239.     // empty<T>.
  240.     template <class D>
  241.     reference get_default(D const&, mpl::false_) const
  242.     {
  243.         return arg.value;
  244.     }
  245.  
  246.     template <class D>
  247.     reference get_default(D const& d, mpl::true_) const
  248.     {
  249.         return arg.value ? arg.value.get() : arg.value.construct(d.value);
  250.     }
  251.  
  252. #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  253.     // These older compilers don't support the overload set creation
  254.     // idiom well, so we need to do all the return type calculation
  255.     // for the compiler and dispatch through an outer function template
  256.  
  257.     // A metafunction class that, given a keyword, returns the base
  258.     // sublist whose get() function can produce the value for that
  259.     // key.
  260.     struct key_owner
  261.     {
  262.         template<class KW>
  263.         struct apply
  264.         {
  265.           typedef typename mpl::eval_if<
  266.                 mars_boost::is_same<KW, key_type>
  267.               , mpl::identity<arg_list<TaggedArg,Next> >
  268.               , mpl::apply_wrap1<typename Next::key_owner,KW>
  269.           >::type type;
  270.         };
  271.     };
  272.  
  273.     // Outer indexing operators that dispatch to the right node's
  274.     // get() function.
  275.     template <class KW>
  276.     typename mpl::apply_wrap3<binding, KW, void_, mpl::true_>::type
  277.     operator[](keyword<KW> const& x) const
  278.     {
  279.         typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
  280.         return sublist.get(x);
  281.     }
  282.  
  283.     template <class KW, class Default>
  284.     typename mpl::apply_wrap3<binding, KW, Default&, mpl::true_>::type
  285.     operator[](default_<KW, Default> x) const
  286.     {
  287.         typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
  288.         return sublist.get(x);
  289.     }
  290.  
  291.     template <class KW, class F>
  292.     typename mpl::apply_wrap3<
  293.         binding,KW
  294.       , typename result_of0<F>::type
  295.       , mpl::true_
  296.     >::type
  297.     operator[](lazy_default<KW,F> x) const
  298.     {
  299.         typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
  300.         return sublist.get(x);
  301.     }
  302.  
  303.     // These just return the stored value; when empty_arg_list is
  304.     // reached, indicating no matching argument was passed, the
  305.     // default is returned, or if no default_ or lazy_default was
  306.     // passed, compilation fails.
  307.     reference get(keyword<key_type> const&) const
  308.     {
  309.         BOOST_MPL_ASSERT_NOT((holds_maybe));
  310.         return arg.value;
  311.     }
  312.  
  313.     template <class Default>
  314.     reference get(default_<key_type,Default> const& d) const
  315.     {
  316.         return get_default(d, holds_maybe());
  317.     }
  318.  
  319.     template <class Default>
  320.     reference get(lazy_default<key_type, Default>) const
  321.     {
  322.         return arg.value;
  323.     }
  324.  
  325. #else
  326.  
  327.     reference operator[](keyword<key_type> const&) const
  328.     {
  329.         BOOST_MPL_ASSERT_NOT((holds_maybe));
  330.         return arg.value;
  331.     }
  332.  
  333.     template <class Default>
  334.     reference operator[](default_<key_type, Default> const& d) const
  335.     {
  336.         return get_default(d, holds_maybe());
  337.     }
  338.  
  339.     template <class Default>
  340.     reference operator[](lazy_default<key_type, Default>) const
  341.     {
  342.         return arg.value;
  343.     }
  344.  
  345.     // Builds an overload set including operator[]s defined in base
  346.     // classes.
  347.     using Next::operator[];
  348.  
  349.     //
  350.     // End of indexing support
  351.     //
  352.  
  353.  
  354.     //
  355.     // For parameter_requirements matching this node's key_type,
  356.     // return a bool constant wrapper indicating whether the
  357.     // requirements are satisfied by TaggedArg.  Used only for
  358.     // compile-time computation and never really called, so a
  359.     // declaration is enough.
  360.     //
  361.     template <class HasDefault, class Predicate, class ArgPack>
  362.     static typename mpl::apply_wrap2<
  363.         typename mpl::lambda<Predicate, lambda_tag>::type
  364.       , value_type, ArgPack
  365.     >::type
  366.     satisfies(
  367.         parameter_requirements<key_type,Predicate,HasDefault>*
  368.       , ArgPack*
  369.     );
  370.  
  371.     // Builds an overload set including satisfies functions defined
  372.     // in base classes.
  373.     using Next::satisfies;
  374. #endif
  375.  
  376.     // Comma operator to compose argument list without using parameters<>.
  377.     // Useful for argument lists with undetermined length.
  378.     template <class KW, class T2>
  379.     arg_list<tagged_argument<KW, T2>, self>
  380.     operator,(tagged_argument<KW,T2> x) const
  381.     {
  382.         return arg_list<tagged_argument<KW,T2>, self>(x, *this);
  383.     }
  384.  
  385.     // MPL sequence support
  386.     typedef self type;             // Convenience for users
  387.     typedef Next tail_type;        // For the benefit of iterators
  388.     typedef arg_list_tag tag; // For dispatching to sequence intrinsics
  389. };
  390.  
  391. // MPL sequence support
  392. template <class ArgumentPack>
  393. struct arg_list_iterator
  394. {
  395.     typedef mpl::forward_iterator_tag category;
  396.  
  397.     // The incremented iterator
  398.     typedef arg_list_iterator<typename ArgumentPack::tail_type> next;
  399.  
  400.     // dereferencing yields the key type
  401.     typedef typename ArgumentPack::key_type type;
  402. };
  403.  
  404. template <>
  405. struct arg_list_iterator<empty_arg_list> {};
  406.  
  407. }} // namespace parameter::aux
  408.  
  409. // MPL sequence support
  410. namespace mpl
  411. {
  412.   template <>
  413.   struct begin_impl<parameter::aux::arg_list_tag>
  414.   {
  415.       template <class S>
  416.       struct apply
  417.       {
  418.           typedef parameter::aux::arg_list_iterator<S> type;
  419.       };
  420.   };
  421.  
  422.   template <>
  423.   struct end_impl<parameter::aux::arg_list_tag>
  424.   {
  425.       template <class>
  426.       struct apply
  427.       {
  428.           typedef parameter::aux::arg_list_iterator<parameter::aux::empty_arg_list> type;
  429.       };
  430.   };
  431. }
  432.  
  433. } // namespace mars_boost
  434.  
  435. #endif // ARG_LIST_050329_HPP
  436.  
  437.  
downloadarg_list.hpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top