]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/repository/home/qi/primitive/advance.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / spirit / repository / home / qi / primitive / advance.hpp
1 // Copyright (c) 2011 Aaron Graham
2 //
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 #if !defined(BOOST_SPIRIT_REPOSITORY_QI_ADVANCE_JAN_23_2011_1203PM)
7 #define BOOST_SPIRIT_REPOSITORY_QI_ADVANCE_JAN_23_2011_1203PM
8
9 #include <boost/spirit/home/support/terminal.hpp>
10 #include <boost/spirit/include/qi_parse.hpp>
11
12 ///////////////////////////////////////////////////////////////////////////////
13 // definition the place holder
14 namespace boost { namespace spirit { namespace repository { namespace qi
15 {
16 BOOST_SPIRIT_TERMINAL_EX(advance)
17 }}}}
18
19 ///////////////////////////////////////////////////////////////////////////////
20 // implementation the enabler
21 namespace boost { namespace spirit
22 {
23 template <typename A0>
24 struct use_terminal<qi::domain
25 , terminal_ex<repository::qi::tag::advance, fusion::vector1<A0> > >
26 : mpl::or_<is_integral<A0>, is_enum<A0> >
27 {};
28
29 template <>
30 struct use_lazy_terminal<qi::domain, repository::qi::tag::advance, 1>
31 : mpl::true_
32 {};
33 }}
34
35 ///////////////////////////////////////////////////////////////////////////////
36 // implementation of the parser
37 namespace boost { namespace spirit { namespace repository { namespace qi
38 {
39 template <typename Int>
40 struct advance_parser
41 : boost::spirit::qi::primitive_parser< advance_parser<Int> >
42 {
43 // Define the attribute type exposed by this parser component
44 template <typename Context, typename Iterator>
45 struct attribute
46 {
47 typedef boost::spirit::unused_type type;
48 };
49
50 advance_parser(Int dist)
51 : dist(dist)
52 {}
53
54 // This function is called during the actual parsing process
55 template <typename Iterator, typename Context
56 , typename Skipper, typename Attribute>
57 bool parse(Iterator& first, Iterator const& last
58 , Context&, Skipper&, Attribute&) const
59 {
60 // This series of checks is designed to fail parsing on negative
61 // values, without generating a "expression always evaluates true"
62 // warning on unsigned types.
63 if (dist == Int(0)) return true;
64 if (dist < Int(1)) return false;
65
66 typedef typename std::iterator_traits<Iterator>::iterator_category
67 iterator_category;
68 return advance(first, last, iterator_category());
69 }
70
71 // This function is called during error handling to create
72 // a human readable string for the error context.
73 template <typename Context>
74 boost::spirit::info what(Context&) const
75 {
76 return boost::spirit::info("advance");
77 }
78
79 private:
80 // this is the general implementation used by most iterator categories
81 template <typename Iterator, typename IteratorCategory>
82 bool advance(Iterator& first, Iterator const& last
83 , IteratorCategory) const
84 {
85 Int n = dist;
86 Iterator i = first;
87 while (n)
88 {
89 if (i == last) return false;
90 ++i;
91 --n;
92 }
93 first = i;
94 return true;
95 }
96
97 // this is a specialization for random access iterators
98 template <typename Iterator>
99 bool advance(Iterator& first, Iterator const& last
100 , std::random_access_iterator_tag) const
101 {
102 Iterator const it = first + dist;
103 if (it > last) return false;
104 first = it;
105 return true;
106 }
107
108 Int const dist;
109 };
110 }}}}
111
112 ///////////////////////////////////////////////////////////////////////////////
113 // instantiation of the parser
114 namespace boost { namespace spirit { namespace qi
115 {
116 template <typename Modifiers, typename A0>
117 struct make_primitive<
118 terminal_ex<repository::qi::tag::advance, fusion::vector1<A0> >
119 , Modifiers>
120 {
121 typedef repository::qi::advance_parser<A0> result_type;
122
123 template <typename Terminal>
124 result_type operator()(Terminal const& term, unused_type) const
125 {
126 return result_type(fusion::at_c<0>(term.args));
127 }
128 };
129 }}}
130
131 #endif