File indexing completed on 2025-01-18 09:52:30
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_REPOSITORY_QI_ADVANCE_JAN_23_2011_1203PM)
0007 #define BOOST_SPIRIT_REPOSITORY_QI_ADVANCE_JAN_23_2011_1203PM
0008
0009 #include <boost/spirit/home/support/terminal.hpp>
0010 #include <boost/spirit/include/qi_parse.hpp>
0011
0012
0013
0014 namespace boost { namespace spirit { namespace repository { namespace qi
0015 {
0016 BOOST_SPIRIT_TERMINAL_EX(advance)
0017 }}}}
0018
0019
0020
0021 namespace boost { namespace spirit
0022 {
0023 template <typename A0>
0024 struct use_terminal<qi::domain
0025 , terminal_ex<repository::qi::tag::advance, fusion::vector1<A0> > >
0026 : mpl::or_<is_integral<A0>, is_enum<A0> >
0027 {};
0028
0029 template <>
0030 struct use_lazy_terminal<qi::domain, repository::qi::tag::advance, 1>
0031 : mpl::true_
0032 {};
0033 }}
0034
0035
0036
0037 namespace boost { namespace spirit { namespace repository { namespace qi
0038 {
0039 template <typename Int>
0040 struct advance_parser
0041 : boost::spirit::qi::primitive_parser< advance_parser<Int> >
0042 {
0043
0044 template <typename Context, typename Iterator>
0045 struct attribute
0046 {
0047 typedef boost::spirit::unused_type type;
0048 };
0049
0050 advance_parser(Int dist)
0051 : dist(dist)
0052 {}
0053
0054
0055 template <typename Iterator, typename Context
0056 , typename Skipper, typename Attribute>
0057 bool parse(Iterator& first, Iterator const& last
0058 , Context&, Skipper&, Attribute&) const
0059 {
0060
0061
0062
0063 if (dist == Int(0)) return true;
0064 if (dist < Int(1)) return false;
0065
0066 typedef typename std::iterator_traits<Iterator>::iterator_category
0067 iterator_category;
0068 return advance(first, last, iterator_category());
0069 }
0070
0071
0072
0073 template <typename Context>
0074 boost::spirit::info what(Context&) const
0075 {
0076 return boost::spirit::info("advance");
0077 }
0078
0079 private:
0080
0081 template <typename Iterator, typename IteratorCategory>
0082 bool advance(Iterator& first, Iterator const& last
0083 , IteratorCategory) const
0084 {
0085 Int n = dist;
0086 Iterator i = first;
0087 while (n)
0088 {
0089 if (i == last) return false;
0090 ++i;
0091 --n;
0092 }
0093 first = i;
0094 return true;
0095 }
0096
0097
0098 template <typename Iterator>
0099 bool advance(Iterator& first, Iterator const& last
0100 , std::random_access_iterator_tag) const
0101 {
0102 Iterator const it = first + dist;
0103 if (it > last) return false;
0104 first = it;
0105 return true;
0106 }
0107
0108 Int const dist;
0109 };
0110 }}}}
0111
0112
0113
0114 namespace boost { namespace spirit { namespace qi
0115 {
0116 template <typename Modifiers, typename A0>
0117 struct make_primitive<
0118 terminal_ex<repository::qi::tag::advance, fusion::vector1<A0> >
0119 , Modifiers>
0120 {
0121 typedef repository::qi::advance_parser<A0> result_type;
0122
0123 template <typename Terminal>
0124 result_type operator()(Terminal const& term, unused_type) const
0125 {
0126 return result_type(fusion::at_c<0>(term.args));
0127 }
0128 };
0129 }}}
0130
0131 #endif