• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2014 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 #ifndef BOOST_SPIRIT_X3_DIRECTIVE_RAW_HPP
8 #define BOOST_SPIRIT_X3_DIRECTIVE_RAW_HPP
9 
10 #include <boost/spirit/home/x3/core/skip_over.hpp>
11 #include <boost/spirit/home/x3/core/parser.hpp>
12 #include <boost/spirit/home/x3/support/traits/move_to.hpp>
13 #include <boost/spirit/home/x3/support/traits/pseudo_attribute.hpp>
14 #include <boost/range/iterator_range_core.hpp>
15 
16 namespace boost { namespace spirit { namespace x3
17 {
18     // this is a pseudo attribute type indicating that the parser wants the
19     // iterator range pointing to the [first, last) matching characters from
20     // the input iterators.
21     struct raw_attribute_type {};
22 
23     template <typename Subject>
24     struct raw_directive : unary_parser<Subject, raw_directive<Subject>>
25     {
26         typedef unary_parser<Subject, raw_directive<Subject> > base_type;
27         typedef raw_attribute_type attribute_type;
28         static bool const handles_container = Subject::handles_container;
29         typedef Subject subject_type;
30 
raw_directiveboost::spirit::x3::raw_directive31         constexpr raw_directive(Subject const& subject)
32           : base_type(subject) {}
33 
34         template <typename Iterator, typename Context
35             , typename RContext, typename Attribute>
parseboost::spirit::x3::raw_directive36         bool parse(Iterator& first, Iterator const& last
37           , Context const& context, RContext& rcontext, Attribute& attr) const
38         {
39             x3::skip_over(first, last, context);
40             Iterator i = first;
41             if (this->subject.parse(i, last, context, rcontext, unused))
42             {
43                 traits::move_to(first, i, attr);
44                 first = i;
45                 return true;
46             }
47             return false;
48         }
49 
50         template <typename Iterator, typename Context, typename RContext>
parseboost::spirit::x3::raw_directive51         bool parse(Iterator& first, Iterator const& last
52           , Context const& context, RContext& rcontext, unused_type) const
53         {
54             return this->subject.parse(first, last, context, rcontext, unused);
55         }
56     };
57 
58     struct raw_gen
59     {
60         template <typename Subject>
61         constexpr raw_directive<typename extension::as_parser<Subject>::value_type>
operator []boost::spirit::x3::raw_gen62         operator[](Subject const& subject) const
63         {
64             return { as_parser(subject) };
65         }
66     };
67 
68     constexpr auto raw = raw_gen{};
69 
70     namespace traits
71     {
72         template <typename Context, typename Iterator>
73         struct pseudo_attribute<Context, raw_attribute_type, Iterator>
74         {
75             using attribute_type = raw_attribute_type;
76             using type = boost::iterator_range<Iterator>;
77 
callboost::spirit::x3::traits::pseudo_attribute78             static type call(Iterator& first, Iterator const& last, attribute_type)
79             {
80                 return { first, last };
81             }
82         };
83     }
84 }}}
85 
86 #endif
87