raw.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_RAW_HPP
  7. #define BOOST_SPIRIT_X3_DIRECTIVE_RAW_HPP
  8. #include <boost/spirit/home/x3/core/skip_over.hpp>
  9. #include <boost/spirit/home/x3/core/parser.hpp>
  10. #include <boost/spirit/home/x3/support/traits/move_to.hpp>
  11. #include <boost/spirit/home/x3/support/traits/pseudo_attribute.hpp>
  12. #include <boost/range/iterator_range_core.hpp>
  13. namespace boost { namespace spirit { namespace x3
  14. {
  15. // this is a pseudo attribute type indicating that the parser wants the
  16. // iterator range pointing to the [first, last) matching characters from
  17. // the input iterators.
  18. struct raw_attribute_type {};
  19. template <typename Subject>
  20. struct raw_directive : unary_parser<Subject, raw_directive<Subject>>
  21. {
  22. typedef unary_parser<Subject, raw_directive<Subject> > base_type;
  23. typedef raw_attribute_type attribute_type;
  24. static bool const handles_container = true;
  25. typedef Subject subject_type;
  26. constexpr raw_directive(Subject const& subject)
  27. : base_type(subject) {}
  28. template <typename Iterator, typename Context
  29. , typename RContext, typename Attribute>
  30. bool parse(Iterator& first, Iterator const& last
  31. , Context const& context, RContext& rcontext, Attribute& attr) const
  32. {
  33. x3::skip_over(first, last, context);
  34. Iterator i = first;
  35. if (this->subject.parse(i, last, context, rcontext, unused))
  36. {
  37. traits::move_to(first, i, attr);
  38. first = i;
  39. return true;
  40. }
  41. return false;
  42. }
  43. template <typename Iterator, typename Context, typename RContext>
  44. bool parse(Iterator& first, Iterator const& last
  45. , Context const& context, RContext& rcontext, unused_type) const
  46. {
  47. return this->subject.parse(first, last, context, rcontext, unused);
  48. }
  49. };
  50. struct raw_gen
  51. {
  52. template <typename Subject>
  53. constexpr raw_directive<typename extension::as_parser<Subject>::value_type>
  54. operator[](Subject const& subject) const
  55. {
  56. return { as_parser(subject) };
  57. }
  58. };
  59. constexpr auto raw = raw_gen{};
  60. namespace traits
  61. {
  62. template <typename Context, typename Iterator>
  63. struct pseudo_attribute<Context, raw_attribute_type, Iterator>
  64. {
  65. using attribute_type = raw_attribute_type;
  66. using type = boost::iterator_range<Iterator>;
  67. static type call(Iterator& first, Iterator const& last, attribute_type)
  68. {
  69. return { first, last };
  70. }
  71. };
  72. }
  73. }}}
  74. #endif