]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/qi/string/lit.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / 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 // silence MSVC warning C4512: assignment operator could not be generated
122 BOOST_DELETED_FUNCTION(literal_string& operator= (literal_string const&))
123 };
124
125 template <typename String, bool no_attribute>
126 struct no_case_literal_string
127 : primitive_parser<no_case_literal_string<String, no_attribute> >
128 {
129 typedef typename
130 remove_const<typename traits::char_type_of<String>::type>::type
131 char_type;
132 typedef std::basic_string<char_type> string_type;
133
134 template <typename CharEncoding>
135 no_case_literal_string(char_type const* in, CharEncoding encoding)
136 : str_lo(in)
137 , str_hi(in)
138 {
139 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
140 (void)encoding; // suppresses warning: C4100: 'encoding' : unreferenced formal parameter
141 #endif
142 typename string_type::iterator loi = str_lo.begin();
143 typename string_type::iterator hii = str_hi.begin();
144
145 for (; loi != str_lo.end(); ++loi, ++hii, ++in)
146 {
147 typedef typename CharEncoding::char_type encoded_char_type;
148
149 *loi = static_cast<char_type>(encoding.tolower(encoded_char_type(*loi)));
150 *hii = static_cast<char_type>(encoding.toupper(encoded_char_type(*hii)));
151 }
152 }
153
154 template <typename Context, typename Iterator>
155 struct attribute
156 {
157 typedef typename mpl::if_c<
158 no_attribute, unused_type, string_type>::type
159 type;
160 };
161
162 template <typename Iterator, typename Context
163 , typename Skipper, typename Attribute>
164 bool parse(Iterator& first, Iterator const& last
165 , Context& /*context*/, Skipper const& skipper, Attribute& attr_) const
166 {
167 qi::skip_over(first, last, skipper);
168 return detail::string_parse(str_lo, str_hi, first, last, attr_);
169 }
170
171 template <typename Context>
172 info what(Context& /*context*/) const
173 {
174 return info("no-case-literal-string", str_lo);
175 }
176
177 string_type str_lo, str_hi;
178 };
179
180 ///////////////////////////////////////////////////////////////////////////
181 // Parser generators: make_xxx function (objects)
182 ///////////////////////////////////////////////////////////////////////////
183 template <typename T, typename Modifiers>
184 struct make_primitive<T, Modifiers
185 , typename enable_if<traits::is_string<T> >::type>
186 {
187 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
188
189 typedef typename add_const<T>::type const_string;
190 typedef typename mpl::if_<
191 no_case
192 , no_case_literal_string<const_string, true>
193 , literal_string<const_string, true> >::type
194 result_type;
195
196 result_type operator()(
197 typename add_reference<const_string>::type str, unused_type) const
198 {
199 return op(str, no_case());
200 }
201
202 template <typename String>
203 result_type op(String const& str, mpl::false_) const
204 {
205 return result_type(str);
206 }
207
208 template <typename String>
209 result_type op(String const& str, mpl::true_) const
210 {
211 typename spirit::detail::get_encoding<Modifiers,
212 spirit::char_encoding::standard>::type encoding;
213 return result_type(traits::get_c_string(str), encoding);
214 }
215 };
216
217 // lit("...")
218 template <typename Modifiers, typename A0>
219 struct make_primitive<
220 terminal_ex<tag::lit, fusion::vector1<A0> >
221 , Modifiers
222 , typename enable_if<traits::is_string<A0> >::type>
223 {
224 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
225
226 typedef typename add_const<A0>::type const_string;
227 typedef typename mpl::if_<
228 no_case
229 , no_case_literal_string<const_string, true>
230 , literal_string<const_string, true> >::type
231 result_type;
232
233 template <typename Terminal>
234 result_type operator()(Terminal const& term, unused_type) const
235 {
236 return op(fusion::at_c<0>(term.args), no_case());
237 }
238
239 template <typename String>
240 result_type op(String const& str, mpl::false_) const
241 {
242 return result_type(str);
243 }
244
245 template <typename String>
246 result_type op(String const& str, mpl::true_) const
247 {
248 typedef typename traits::char_encoding_from_char<
249 typename traits::char_type_of<A0>::type>::type encoding_type;
250 typename spirit::detail::get_encoding<Modifiers,
251 encoding_type>::type encoding;
252 return result_type(traits::get_c_string(str), encoding);
253 }
254 };
255
256 ///////////////////////////////////////////////////////////////////////////
257 // string("...")
258 template <typename CharEncoding, typename Modifiers, typename A0>
259 struct make_primitive<
260 terminal_ex<
261 tag::char_code<tag::string, CharEncoding>
262 , fusion::vector1<A0> >
263 , Modifiers>
264 {
265 typedef CharEncoding encoding;
266 typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
267
268 typedef typename add_const<A0>::type const_string;
269 typedef typename mpl::if_<
270 no_case
271 , no_case_literal_string<const_string, false>
272 , literal_string<const_string, false> >::type
273 result_type;
274
275 template <typename Terminal>
276 result_type operator()(Terminal const& term, unused_type) const
277 {
278 return op(fusion::at_c<0>(term.args), no_case());
279 }
280
281 template <typename String>
282 result_type op(String const& str, mpl::false_) const
283 {
284 return result_type(str);
285 }
286
287 template <typename String>
288 result_type op(String const& str, mpl::true_) const
289 {
290 return result_type(traits::get_c_string(str), encoding());
291 }
292 };
293 }}}
294
295 namespace boost { namespace spirit { namespace traits
296 {
297 ///////////////////////////////////////////////////////////////////////////
298 template <typename String, bool no_attribute, typename Attribute
299 ,typename Context, typename Iterator>
300 struct handles_container<qi::literal_string<String, no_attribute>
301 , Attribute, Context, Iterator>
302 : mpl::true_ {};
303
304 template <typename String, bool no_attribute, typename Attribute
305 , typename Context, typename Iterator>
306 struct handles_container<qi::no_case_literal_string<String, no_attribute>
307 , Attribute, Context, Iterator>
308 : mpl::true_ {};
309 }}}
310
311 #endif