]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/karma/string/lit.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / karma / string / lit.hpp
1 // Copyright (c) 2001-2011 Hartmut Kaiser
2 // Copyright (c) 2010 Bryce Lelbach
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 #if !defined(BOOST_SPIRIT_KARMA_LIT_FEB_22_2007_0534PM)
8 #define BOOST_SPIRIT_KARMA_LIT_FEB_22_2007_0534PM
9
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13
14 #include <boost/spirit/home/support/common_terminals.hpp>
15 #include <boost/spirit/home/support/string_traits.hpp>
16 #include <boost/spirit/home/support/info.hpp>
17 #include <boost/spirit/home/support/char_class.hpp>
18 #include <boost/spirit/home/support/container.hpp>
19 #include <boost/spirit/home/support/handles_container.hpp>
20 #include <boost/spirit/home/support/detail/get_encoding.hpp>
21 #include <boost/spirit/home/karma/domain.hpp>
22 #include <boost/spirit/home/karma/meta_compiler.hpp>
23 #include <boost/spirit/home/karma/delimit_out.hpp>
24 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
25 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
26 #include <boost/spirit/home/karma/detail/extract_from.hpp>
27 #include <boost/spirit/home/karma/detail/string_generate.hpp>
28 #include <boost/spirit/home/karma/detail/string_compare.hpp>
29 #include <boost/spirit/home/karma/detail/enable_lit.hpp>
30 #include <boost/fusion/include/at.hpp>
31 #include <boost/fusion/include/vector.hpp>
32 #include <boost/fusion/include/cons.hpp>
33 #include <boost/mpl/if.hpp>
34 #include <boost/mpl/or.hpp>
35 #include <boost/mpl/assert.hpp>
36 #include <boost/mpl/bool.hpp>
37 #include <boost/utility/enable_if.hpp>
38 #include <string>
39
40 ///////////////////////////////////////////////////////////////////////////////
41 namespace boost { namespace spirit
42 {
43 ///////////////////////////////////////////////////////////////////////////
44 // Enablers
45 ///////////////////////////////////////////////////////////////////////////
46 template <typename CharEncoding>
47 struct use_terminal<karma::domain
48 , tag::char_code<tag::string, CharEncoding> > // enables string
49 : mpl::true_ {};
50
51 template <typename T>
52 struct use_terminal<karma::domain, T
53 , typename enable_if<traits::is_string<T> >::type> // enables string literals
54 : mpl::true_ {};
55
56 template <typename CharEncoding, typename A0>
57 struct use_terminal<karma::domain
58 , terminal_ex<
59 tag::char_code<tag::string, CharEncoding> // enables string(str)
60 , fusion::vector1<A0> >
61 > : traits::is_string<A0> {};
62
63 template <typename CharEncoding> // enables string(f)
64 struct use_lazy_terminal<
65 karma::domain
66 , tag::char_code<tag::string, CharEncoding>
67 , 1 /*arity*/
68 > : mpl::true_ {};
69
70 // enables lit(str)
71 template <typename A0>
72 struct use_terminal<karma::domain
73 , terminal_ex<tag::lit, fusion::vector1<A0> >
74 , typename enable_if<traits::is_string<A0> >::type>
75 : mpl::true_ {};
76 }}
77
78 ///////////////////////////////////////////////////////////////////////////////
79 namespace boost { namespace spirit { namespace karma
80 {
81 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
82 using spirit::lit;
83 #endif
84 using spirit::lit_type;
85
86 ///////////////////////////////////////////////////////////////////////////
87 // generate literal strings from a given parameter
88 ///////////////////////////////////////////////////////////////////////////
89 template <typename CharEncoding, typename Tag>
90 struct any_string
91 : primitive_generator<any_string<CharEncoding, Tag> >
92 {
93 typedef typename CharEncoding::char_type char_type;
94 typedef CharEncoding char_encoding;
95
96 template <typename Context, typename Unused = unused_type>
97 struct attribute
98 {
99 typedef std::basic_string<char_type> type;
100 };
101
102 // lit has an attached attribute
103 template <typename OutputIterator, typename Context, typename Delimiter
104 , typename Attribute>
105 static bool
106 generate(OutputIterator& sink, Context& context, Delimiter const& d,
107 Attribute const& attr)
108 {
109 if (!traits::has_optional_value(attr))
110 return false;
111
112 typedef typename attribute<Context>::type attribute_type;
113 return
114 karma::detail::string_generate(sink
115 , traits::extract_from<attribute_type>(attr, context)
116 , char_encoding(), Tag()) &&
117 karma::delimit_out(sink, d); // always do post-delimiting
118 }
119
120 // this lit has no attribute attached, it needs to have been
121 // initialized from a direct literal
122 template <typename OutputIterator, typename Context, typename Delimiter>
123 static bool generate(OutputIterator&, Context&, Delimiter const&,
124 unused_type const&)
125 {
126 // It is not possible (doesn't make sense) to use string without
127 // providing any attribute, as the generator doesn't 'know' what
128 // character to output. The following assertion fires if this
129 // situation is detected in your code.
130 BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, string_not_usable_without_attribute, ());
131 return false;
132 }
133
134 template <typename Context>
135 static info what(Context const& /*context*/)
136 {
137 return info("any-string");
138 }
139 };
140
141 ///////////////////////////////////////////////////////////////////////////
142 // generate literal strings
143 ///////////////////////////////////////////////////////////////////////////
144 template <typename String, typename CharEncoding, typename Tag, bool no_attribute>
145 struct literal_string
146 : primitive_generator<literal_string<String, CharEncoding, Tag, no_attribute> >
147 {
148 typedef CharEncoding char_encoding;
149 typedef typename
150 remove_const<typename traits::char_type_of<String>::type>::type
151 char_type;
152 typedef std::basic_string<char_type> string_type;
153
154 template <typename Context, typename Unused = unused_type>
155 struct attribute
156 : mpl::if_c<no_attribute, unused_type, string_type>
157 {};
158
159 literal_string(typename add_reference<String>::type str)
160 : str_(str)
161 {}
162
163 // A string("...") which additionally has an associated attribute emits
164 // its immediate literal only if it matches the attribute, otherwise
165 // it fails.
166 template <
167 typename OutputIterator, typename Context, typename Delimiter
168 , typename Attribute>
169 bool generate(OutputIterator& sink, Context& context
170 , Delimiter const& d, Attribute const& attr) const
171 {
172 if (!traits::has_optional_value(attr))
173 return false;
174
175 // fail if attribute isn't matched by immediate literal
176 typedef typename attribute<Context>::type attribute_type;
177
178 using spirit::traits::get_c_string;
179 if (!detail::string_compare(
180 get_c_string(
181 traits::extract_from<attribute_type>(attr, context))
182 , get_c_string(str_), char_encoding(), Tag()))
183 {
184 return false;
185 }
186 return detail::string_generate(sink, str_, char_encoding(), Tag()) &&
187 karma::delimit_out(sink, d); // always do post-delimiting
188 }
189
190 // A string("...") without any associated attribute just emits its
191 // immediate literal
192 template <typename OutputIterator, typename Context, typename Delimiter>
193 bool generate(OutputIterator& sink, Context&, Delimiter const& d
194 , unused_type) const
195 {
196 return detail::string_generate(sink, str_, char_encoding(), Tag()) &&
197 karma::delimit_out(sink, d); // always do post-delimiting
198 }
199
200 template <typename Context>
201 info what(Context const& /*context*/) const
202 {
203 return info("literal-string", str_);
204 }
205
206 string_type str_;
207 };
208
209 ///////////////////////////////////////////////////////////////////////////
210 // Generator generators: make_xxx function (objects)
211 ///////////////////////////////////////////////////////////////////////////
212
213 // string
214 template <typename CharEncoding, typename Modifiers>
215 struct make_primitive<
216 tag::char_code<tag::string, CharEncoding>
217 , Modifiers>
218 {
219 static bool const lower =
220 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
221 static bool const upper =
222 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
223
224 typedef any_string<
225 typename spirit::detail::get_encoding_with_case<
226 Modifiers, CharEncoding, lower || upper>::type
227 , typename detail::get_casetag<Modifiers, lower || upper>::type
228 > result_type;
229
230 result_type operator()(unused_type, unused_type) const
231 {
232 return result_type();
233 }
234 };
235
236 // string literal
237 template <typename T, typename Modifiers>
238 struct make_primitive<T, Modifiers
239 , typename enable_if<traits::is_string<T> >::type>
240 {
241 static bool const lower =
242 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
243
244 static bool const upper =
245 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
246
247 typedef typename add_const<T>::type const_string;
248 typedef literal_string<
249 const_string
250 , typename spirit::detail::get_encoding_with_case<
251 Modifiers, unused_type, lower || upper>::type
252 , typename detail::get_casetag<Modifiers, lower || upper>::type
253 , true
254 > result_type;
255
256 result_type operator()(
257 typename add_reference<const_string>::type str, unused_type) const
258 {
259 return result_type(str);
260 }
261 };
262
263 ///////////////////////////////////////////////////////////////////////////
264 namespace detail
265 {
266 template <typename CharEncoding, typename Modifiers, typename A0
267 , bool no_attribute>
268 struct make_string_direct
269 {
270 static bool const lower =
271 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
272 static bool const upper =
273 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
274
275 typedef typename add_const<A0>::type const_string;
276 typedef literal_string<
277 const_string
278 , typename spirit::detail::get_encoding_with_case<
279 Modifiers, unused_type, lower || upper>::type
280 , typename detail::get_casetag<Modifiers, lower || upper>::type
281 , no_attribute
282 > result_type;
283
284 template <typename Terminal>
285 result_type operator()(Terminal const& term, unused_type) const
286 {
287 return result_type(fusion::at_c<0>(term.args));
288 }
289 };
290 }
291
292 // string("..."), lit("...")
293 template <typename CharEncoding, typename Modifiers, typename A0>
294 struct make_primitive<
295 terminal_ex<
296 tag::char_code<tag::string, CharEncoding>
297 , fusion::vector1<A0> >
298 , Modifiers>
299 : detail::make_string_direct<CharEncoding, Modifiers, A0, false>
300 {};
301
302 template <typename Modifiers, typename A0>
303 struct make_primitive<
304 terminal_ex<tag::lit, fusion::vector1<A0> >
305 , Modifiers
306 , typename enable_if<traits::is_string<A0> >::type>
307 : detail::make_string_direct<
308 typename traits::char_encoding_from_char<
309 typename traits::char_type_of<A0>::type>::type
310 , Modifiers, A0, true>
311 {};
312 }}} // namespace boost::spirit::karma
313
314 namespace boost { namespace spirit { namespace traits
315 {
316 ///////////////////////////////////////////////////////////////////////////
317 template <typename CharEncoding, typename Tag, typename Attribute
318 , typename Context, typename Iterator>
319 struct handles_container<karma::any_string<CharEncoding, Tag>, Attribute
320 , Context, Iterator>
321 : mpl::false_ {};
322
323 template <typename String, typename CharEncoding, typename Tag
324 , bool no_attribute, typename Attribute, typename Context
325 , typename Iterator>
326 struct handles_container<karma::literal_string<String, CharEncoding, Tag
327 , no_attribute>, Attribute, Context, Iterator>
328 : mpl::false_ {};
329 }}}
330
331 #endif