]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/qi/string/lit.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / qi / string / lit.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3 Copyright (c) 2001-2011 Hartmut Kaiser
4 Copyright (c) 2010 Bryce Lelbach
5
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
9 #if !defined(BOOST_SPIRIT_LIT_APR_18_2006_1125PM)
10 #define BOOST_SPIRIT_LIT_APR_18_2006_1125PM
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
16 #include <boost/spirit/home/qi/domain.hpp>
17 #include <boost/spirit/home/qi/skip_over.hpp>
18 #include <boost/spirit/home/qi/detail/string_parse.hpp>
19 #include <boost/spirit/home/qi/parser.hpp>
20 #include <boost/spirit/home/qi/meta_compiler.hpp>
21 #include <boost/spirit/home/qi/auxiliary/lazy.hpp>
22 #include <boost/spirit/home/qi/detail/enable_lit.hpp>
23 #include <boost/spirit/home/support/info.hpp>
24 #include <boost/spirit/home/support/char_class.hpp>
25 #include <boost/spirit/home/support/modify.hpp>
26 #include <boost/spirit/home/support/unused.hpp>
27 #include <boost/spirit/home/support/common_terminals.hpp>
28 #include <boost/spirit/home/support/string_traits.hpp>
29 #include <boost/spirit/home/support/detail/get_encoding.hpp>
30 #include <boost/spirit/home/support/handles_container.hpp>
31 #include <boost/fusion/include/at.hpp>
32 #include <boost/fusion/include/value_at.hpp>
33 #include <boost/type_traits/add_reference.hpp>
34 #include <boost/type_traits/add_const.hpp>
35 #include <boost/mpl/assert.hpp>
36 #include <boost/mpl/if.hpp>
37 #include <boost/detail/workaround.hpp>
38 #include <boost/utility/enable_if.hpp>
39 #include <string>
40
41 namespace boost { namespace spirit
42 {
43 ///////////////////////////////////////////////////////////////////////////
44 // Enablers
45 ///////////////////////////////////////////////////////////////////////////
46 template <typename T>
47 struct use_terminal<qi::domain, T
48 , typename enable_if<traits::is_string<T> >::type> // enables strings
49 : mpl::true_ {};
50
51 template <typename CharEncoding, typename A0>
52 struct use_terminal<qi::domain
53 , terminal_ex<
54 tag::char_code<tag::string, CharEncoding> // enables string(str)
55 , fusion::vector1<A0> >
56 > : traits::is_string<A0> {};
57
58 template <typename CharEncoding> // enables string(f)
59 struct use_lazy_terminal<
60 qi::domain
61 , tag::char_code<tag::string, CharEncoding>
62 , 1 /*arity*/
63 > : mpl::true_ {};
64
65 // enables lit(...)
66 template <typename A0>
67 struct use_terminal<qi::domain
68 , terminal_ex<tag::lit, fusion::vector1<A0> >
69 , typename enable_if<traits::is_string<A0> >::type>
70 : mpl::true_ {};
71 }}
72
73 namespace boost { namespace spirit { namespace qi
74 {
75 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
76 using spirit::lit;
77 #endif
78 using spirit::lit_type;
79
80 ///////////////////////////////////////////////////////////////////////////
81 // Parse for literal strings
82 ///////////////////////////////////////////////////////////////////////////
83 template <typename String, bool no_attribute>
84 struct literal_string
85 : primitive_parser<literal_string<String, no_attribute> >
86 {
87 typedef typename
88 remove_const<typename traits::char_type_of<String>::type>::type
89 char_type;
90 typedef std::basic_string<char_type> string_type;
91
92 literal_string(typename add_reference<String>::type str_)
93 : str(str_)
94 {}
95
96 template <typename Context, typename Iterator>
97 struct attribute
98 {
99 typedef typename mpl::if_c<
100 no_attribute, unused_type, string_type>::type
101 type;
102 };
103
104 template <typename Iterator, typename Context
105 , typename Skipper, typename Attribute>
106 bool parse(Iterator& first, Iterator const& last
107 , Context& /*context*/, Skipper const& skipper, Attribute& attr_) const
108 {
109 qi::skip_over(first, last, skipper);
110 return detail::string_parse(str, first, last, attr_);
111 }
112
113 template <typename Context>
114 info what(Context& /*context*/) const
115 {
116 return info("literal-string", str);
117 }
118
119 String str;
120
121 private:
122 // silence MSVC warning C4512: assignment operator could not be generated
123 literal_string& operator= (literal_string const&);
124 };
125
126 template <typename String, bool no_attribute>
127 struct no_case_literal_string
128 : primitive_parser<no_case_literal_string<String, no_attribute> >
129 {
130 typedef typename
131 remove_const<typename traits::char_type_of<String>::type>::type
132 char_type;
133 typedef std::basic_string<char_type> string_type;
134
135 template <typename CharEncoding>
136 no_case_literal_string(char_type const* in, CharEncoding encoding)
137 : str_lo(in)
138 , str_hi(in)
139 {
140 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
141 encoding; // suppresses warning: C4100: 'encoding' : unreferenced formal parameter
142 #endif
143 typename string_type::iterator loi = str_lo.begin();
144 typename string_type::iterator hii = str_hi.begin();
145
146 for (; loi != str_lo.end(); ++loi, ++hii, ++in)
147 {
148 typedef typename CharEncoding::char_type encoded_char_type;
149
150 *loi = static_cast<char_type>(encoding.tolower(encoded_char_type(*loi)));
151 *hii = static_cast<char_type>(encoding.toupper(encoded_char_type(*hii)));
152 }
153 }
154
155 template <typename Context, typename Iterator>
156 struct attribute
157 {
158 typedef typename mpl::if_c<
159 no_attribute, unused_type, string_type>::type
160 type;
161 };
162
163 template <typename Iterator, typename Context
164 , typename Skipper, typename Attribute>
165 bool parse(Iterator& first, Iterator const& last
166 , Context& /*context*/, Skipper const& skipper, Attribute& attr_) const
167 {
168 qi::skip_over(first, last, skipper);
169 return detail::string_parse(str_lo, str_hi, first, last, attr_);
170 }
171
172 template <typename Context>
173 info what(Context& /*context*/) const
174 {
175 return info("no-case-literal-string", str_lo);
176 }
177
178 string_type str_lo, str_hi;
179 };
180
181 ///////////////////////////////////////////////////////////////////////////
182 // Parser generators: make_xxx function (objects)
183 ///////////////////////////////////////////////////////////////////////////
184 template <typename T, typename Modifiers>
185 struct make_primitive<T, Modifiers
186 , typename enable_if<traits::is_string<T> >::type>
187 {
188 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
189
190 typedef typename add_const<T>::type const_string;
191 typedef typename mpl::if_<
192 no_case
193 , no_case_literal_string<const_string, true>
194 , literal_string<const_string, true> >::type
195 result_type;
196
197 result_type operator()(
198 typename add_reference<const_string>::type str, unused_type) const
199 {
200 return op(str, no_case());
201 }
202
203 template <typename String>
204 result_type op(String const& str, mpl::false_) const
205 {
206 return result_type(str);
207 }
208
209 template <typename String>
210 result_type op(String const& str, mpl::true_) const
211 {
212 typename spirit::detail::get_encoding<Modifiers,
213 spirit::char_encoding::standard>::type encoding;
214 return result_type(traits::get_c_string(str), encoding);
215 }
216 };
217
218 // lit("...")
219 template <typename Modifiers, typename A0>
220 struct make_primitive<
221 terminal_ex<tag::lit, fusion::vector1<A0> >
222 , Modifiers
223 , typename enable_if<traits::is_string<A0> >::type>
224 {
225 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
226
227 typedef typename add_const<A0>::type const_string;
228 typedef typename mpl::if_<
229 no_case
230 , no_case_literal_string<const_string, true>
231 , literal_string<const_string, true> >::type
232 result_type;
233
234 template <typename Terminal>
235 result_type operator()(Terminal const& term, unused_type) const
236 {
237 return op(fusion::at_c<0>(term.args), no_case());
238 }
239
240 template <typename String>
241 result_type op(String const& str, mpl::false_) const
242 {
243 return result_type(str);
244 }
245
246 template <typename String>
247 result_type op(String const& str, mpl::true_) const
248 {
249 typedef typename traits::char_encoding_from_char<
250 typename traits::char_type_of<A0>::type>::type encoding_type;
251 typename spirit::detail::get_encoding<Modifiers,
252 encoding_type>::type encoding;
253 return result_type(traits::get_c_string(str), encoding);
254 }
255 };
256
257 ///////////////////////////////////////////////////////////////////////////
258 // string("...")
259 template <typename CharEncoding, typename Modifiers, typename A0>
260 struct make_primitive<
261 terminal_ex<
262 tag::char_code<tag::string, CharEncoding>
263 , fusion::vector1<A0> >
264 , Modifiers>
265 {
266 typedef CharEncoding encoding;
267 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
268
269 typedef typename add_const<A0>::type const_string;
270 typedef typename mpl::if_<
271 no_case
272 , no_case_literal_string<const_string, false>
273 , literal_string<const_string, false> >::type
274 result_type;
275
276 template <typename Terminal>
277 result_type operator()(Terminal const& term, unused_type) const
278 {
279 return op(fusion::at_c<0>(term.args), no_case());
280 }
281
282 template <typename String>
283 result_type op(String const& str, mpl::false_) const
284 {
285 return result_type(str);
286 }
287
288 template <typename String>
289 result_type op(String const& str, mpl::true_) const
290 {
291 return result_type(traits::get_c_string(str), encoding());
292 }
293 };
294 }}}
295
296 namespace boost { namespace spirit { namespace traits
297 {
298 ///////////////////////////////////////////////////////////////////////////
299 template <typename String, bool no_attribute, typename Attribute
300 ,typename Context, typename Iterator>
301 struct handles_container<qi::literal_string<String, no_attribute>
302 , Attribute, Context, Iterator>
303 : mpl::true_ {};
304
305 template <typename String, bool no_attribute, typename Attribute
306 , typename Context, typename Iterator>
307 struct handles_container<qi::no_case_literal_string<String, no_attribute>
308 , Attribute, Context, Iterator>
309 : mpl::true_ {};
310 }}}
311
312 #endif