with.hpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*=============================================================================
  2. Copyright (c) 2014 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. =============================================================================*/
  6. #ifndef BOOST_SPIRIT_X3_DIRECTIVE_WITH_HPP
  7. #define BOOST_SPIRIT_X3_DIRECTIVE_WITH_HPP
  8. #include <boost/spirit/home/x3/support/unused.hpp>
  9. #include <boost/spirit/home/x3/core/parser.hpp>
  10. namespace boost { namespace spirit { namespace x3
  11. {
  12. ///////////////////////////////////////////////////////////////////////////
  13. // with directive injects a value into the context prior to parsing.
  14. ///////////////////////////////////////////////////////////////////////////
  15. template <typename Subject, typename Derived, typename T>
  16. struct with_value_holder
  17. : unary_parser<Subject, Derived>
  18. {
  19. typedef unary_parser<Subject, Derived> base_type;
  20. mutable T val;
  21. constexpr with_value_holder(Subject const& subject, T&& val)
  22. : base_type(subject)
  23. , val(std::forward<T>(val)) {}
  24. };
  25. template <typename Subject, typename Derived, typename T>
  26. struct with_value_holder<Subject, Derived, T&>
  27. : unary_parser<Subject, Derived>
  28. {
  29. typedef unary_parser<Subject, Derived> base_type;
  30. T& val;
  31. constexpr with_value_holder(Subject const& subject, T& val)
  32. : base_type(subject)
  33. , val(val) {}
  34. };
  35. template <typename Subject, typename ID, typename T>
  36. struct with_directive
  37. : with_value_holder<Subject, with_directive<Subject, ID, T>, T>
  38. {
  39. typedef with_value_holder<Subject, with_directive<Subject, ID, T>, T> base_type;
  40. static bool const is_pass_through_unary = true;
  41. static bool const handles_container = Subject::handles_container;
  42. typedef Subject subject_type;
  43. constexpr with_directive(Subject const& subject, T&& val)
  44. : base_type(subject, std::forward<T>(val)) {}
  45. template <typename Iterator, typename Context
  46. , typename RContext, typename Attribute>
  47. bool parse(Iterator& first, Iterator const& last
  48. , Context const& context, RContext& rcontext, Attribute& attr) const
  49. {
  50. return this->subject.parse(
  51. first, last
  52. , make_context<ID>(this->val, context)
  53. , rcontext
  54. , attr);
  55. }
  56. };
  57. template <typename ID, typename T>
  58. struct with_gen
  59. {
  60. T&& val;
  61. template <typename Subject>
  62. constexpr with_directive<typename extension::as_parser<Subject>::value_type, ID, T>
  63. operator[](Subject const& subject) const
  64. {
  65. return { as_parser(subject), std::forward<T>(val) };
  66. }
  67. };
  68. template <typename ID, typename T>
  69. constexpr with_gen<ID, T> with(T&& val)
  70. {
  71. return { std::forward<T>(val) };
  72. }
  73. }}}
  74. #endif