]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/x3/core/parser.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / x3 / core / parser.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3 Copyright (c) 2013 Agustin Berge
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #if !defined(BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM)
9 #define BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM
10
11 #include <boost/mpl/bool.hpp>
12 #include <boost/type_traits/is_base_of.hpp>
13 #include <boost/type_traits/remove_cv.hpp>
14 #include <boost/type_traits/remove_reference.hpp>
15 #include <boost/utility/declval.hpp>
16 #include <boost/utility/enable_if.hpp>
17 #include <boost/spirit/home/x3/support/unused.hpp>
18 #include <boost/spirit/home/x3/support/context.hpp>
19 #include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
20 #include <boost/spirit/home/x3/support/utility/sfinae.hpp>
21 #include <string>
22
23 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
24 #include <typeinfo>
25 #endif
26
27 namespace boost { namespace spirit { namespace x3
28 {
29 template <typename Subject, typename Action>
30 struct action;
31
32 template <typename Subject, typename Handler>
33 struct guard;
34
35 struct parser_base {};
36 struct parser_id;
37
38 template <typename Derived>
39 struct parser : parser_base
40 {
41 typedef Derived derived_type;
42 static bool const handles_container = false;
43 static bool const is_pass_through_unary = false;
44 static bool const has_action = false;
45
46 Derived const& derived() const
47 {
48 return *static_cast<Derived const*>(this);
49 }
50
51 template <typename Action>
52 action<Derived, Action>
53 operator[](Action f) const
54 {
55 return action<Derived, Action>(this->derived(), f);
56 }
57
58 template <typename Handler>
59 guard<Derived, Handler>
60 on_error(Handler f) const
61 {
62 return guard<Derived, Handler>(this->derived(), f);
63 }
64 };
65
66 struct unary_category;
67 struct binary_category;
68
69 template <typename Subject, typename Derived>
70 struct unary_parser : parser<Derived>
71 {
72 typedef unary_category category;
73 typedef Subject subject_type;
74 static bool const has_action = Subject::has_action;
75
76 unary_parser(Subject const& subject)
77 : subject(subject) {}
78
79 unary_parser const& get_unary() const { return *this; }
80
81 Subject subject;
82 };
83
84 template <typename Left, typename Right, typename Derived>
85 struct binary_parser : parser<Derived>
86 {
87 typedef binary_category category;
88 typedef Left left_type;
89 typedef Right right_type;
90 static bool const has_action =
91 left_type::has_action || right_type::has_action;
92
93 binary_parser(Left const& left, Right const& right)
94 : left(left), right(right) {}
95
96 binary_parser const& get_binary() const { return *this; }
97
98 Left left;
99 Right right;
100 };
101
102 ///////////////////////////////////////////////////////////////////////////
103 // as_parser: convert a type, T, into a parser.
104 ///////////////////////////////////////////////////////////////////////////
105 namespace extension
106 {
107 namespace detail
108 {
109 namespace as_parser_guard
110 {
111 void as_spirit_parser(...);
112
113 template<typename T, typename R =
114 decltype(as_spirit_parser(boost::declval<T const&>()))>
115 struct deduce_as_parser
116 {
117 typedef R type;
118 typedef typename
119 boost::remove_cv<
120 typename boost::remove_reference<R>::type
121 >::type
122 value_type;
123
124 static type call(T const& v)
125 {
126 return as_spirit_parser(v);
127 }
128 };
129 template<typename T>
130 struct deduce_as_parser<T, void>
131 {};
132 }
133 using as_parser_guard::deduce_as_parser;
134 }
135
136 template <typename T, typename Enable = void>
137 struct as_parser : detail::deduce_as_parser<T> {};
138
139 template <>
140 struct as_parser<unused_type>
141 {
142 typedef unused_type type;
143 typedef unused_type value_type;
144 static type call(unused_type)
145 {
146 return unused;
147 }
148 };
149
150 template <typename Derived>
151 struct as_parser<Derived
152 , typename enable_if<is_base_of<parser_base, Derived>>::type>
153 {
154 typedef Derived const& type;
155 typedef Derived value_type;
156 static type call(Derived const& p)
157 {
158 return p;
159 }
160 };
161
162 template <typename Derived>
163 struct as_parser<parser<Derived>>
164 {
165 typedef Derived const& type;
166 typedef Derived value_type;
167 static type call(parser<Derived> const& p)
168 {
169 return p.derived();
170 }
171 };
172 }
173
174 template <typename T>
175 inline typename extension::as_parser<T>::type
176 as_parser(T const& x)
177 {
178 return extension::as_parser<T>::call(x);
179 }
180
181 template <typename Derived>
182 inline Derived const&
183 as_parser(parser<Derived> const& p)
184 {
185 return p.derived();
186 }
187
188 ///////////////////////////////////////////////////////////////////////////
189 // The main what function
190 //
191 // Note: unlike Spirit2, spirit parsers are no longer required to have a
192 // "what" member function. In X3, we specialize the get_info struct
193 // below where needed. If a specialization is not provided, the default
194 // below will be used. The default "what" result will be the typeid
195 // name of the parser if BOOST_SPIRIT_X3_NO_RTTI is not defined, otherwise
196 // "undefined"
197 ///////////////////////////////////////////////////////////////////////////
198 template <typename Parser, typename Enable = void>
199 struct get_info
200 {
201 typedef std::string result_type;
202 std::string operator()(Parser const&) const
203 {
204 #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
205 return typeid(Parser).name();
206 #else
207 return "undefined";
208 #endif
209 }
210 };
211
212 template <typename Parser>
213 std::string what(Parser const& p)
214 {
215 return get_info<Parser>()(p);
216 }
217 }}}
218
219 namespace boost { namespace spirit { namespace x3 { namespace traits
220 {
221 template <typename Subject, typename Derived, typename Context>
222 struct has_attribute<x3::unary_parser<Subject, Derived>, Context>
223 : has_attribute<Subject, Context> {};
224
225 template <typename Left, typename Right, typename Derived, typename Context>
226 struct has_attribute<x3::binary_parser<Left, Right, Derived>, Context>
227 : mpl::bool_<has_attribute<Left, Context>::value ||
228 has_attribute<Right, Context>::value> {};
229 }}}}
230
231 #endif