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