Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/spirit/home/karma/string/lit.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
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 typedef typename spirit::result_of::extract_from<attribute_type, Attribute>::type | |
179 extracted_string_type; | |
180 | |
181 using spirit::traits::get_c_string; | |
182 if (!detail::string_compare( | |
183 get_c_string( | |
184 traits::extract_from<attribute_type>(attr, context)) | |
185 , get_c_string(str_), char_encoding(), Tag())) | |
186 { | |
187 return false; | |
188 } | |
189 return detail::string_generate(sink, str_, char_encoding(), Tag()) && | |
190 karma::delimit_out(sink, d); // always do post-delimiting | |
191 } | |
192 | |
193 // A string("...") without any associated attribute just emits its | |
194 // immediate literal | |
195 template <typename OutputIterator, typename Context, typename Delimiter> | |
196 bool generate(OutputIterator& sink, Context&, Delimiter const& d | |
197 , unused_type) const | |
198 { | |
199 return detail::string_generate(sink, str_, char_encoding(), Tag()) && | |
200 karma::delimit_out(sink, d); // always do post-delimiting | |
201 } | |
202 | |
203 template <typename Context> | |
204 info what(Context const& /*context*/) const | |
205 { | |
206 return info("literal-string", str_); | |
207 } | |
208 | |
209 string_type str_; | |
210 }; | |
211 | |
212 /////////////////////////////////////////////////////////////////////////// | |
213 // Generator generators: make_xxx function (objects) | |
214 /////////////////////////////////////////////////////////////////////////// | |
215 | |
216 // string | |
217 template <typename CharEncoding, typename Modifiers> | |
218 struct make_primitive< | |
219 tag::char_code<tag::string, CharEncoding> | |
220 , Modifiers> | |
221 { | |
222 static bool const lower = | |
223 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value; | |
224 static bool const upper = | |
225 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value; | |
226 | |
227 typedef any_string< | |
228 typename spirit::detail::get_encoding_with_case< | |
229 Modifiers, CharEncoding, lower || upper>::type | |
230 , typename detail::get_casetag<Modifiers, lower || upper>::type | |
231 > result_type; | |
232 | |
233 result_type operator()(unused_type, unused_type) const | |
234 { | |
235 return result_type(); | |
236 } | |
237 }; | |
238 | |
239 // string literal | |
240 template <typename T, typename Modifiers> | |
241 struct make_primitive<T, Modifiers | |
242 , typename enable_if<traits::is_string<T> >::type> | |
243 { | |
244 static bool const lower = | |
245 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value; | |
246 | |
247 static bool const upper = | |
248 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value; | |
249 | |
250 typedef typename add_const<T>::type const_string; | |
251 typedef literal_string< | |
252 const_string | |
253 , typename spirit::detail::get_encoding_with_case< | |
254 Modifiers, unused_type, lower || upper>::type | |
255 , typename detail::get_casetag<Modifiers, lower || upper>::type | |
256 , true | |
257 > result_type; | |
258 | |
259 result_type operator()( | |
260 typename add_reference<const_string>::type str, unused_type) const | |
261 { | |
262 return result_type(str); | |
263 } | |
264 }; | |
265 | |
266 /////////////////////////////////////////////////////////////////////////// | |
267 namespace detail | |
268 { | |
269 template <typename CharEncoding, typename Modifiers, typename A0 | |
270 , bool no_attribute> | |
271 struct make_string_direct | |
272 { | |
273 static bool const lower = | |
274 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value; | |
275 static bool const upper = | |
276 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value; | |
277 | |
278 typedef typename add_const<A0>::type const_string; | |
279 typedef literal_string< | |
280 const_string | |
281 , typename spirit::detail::get_encoding_with_case< | |
282 Modifiers, unused_type, lower || upper>::type | |
283 , typename detail::get_casetag<Modifiers, lower || upper>::type | |
284 , no_attribute | |
285 > result_type; | |
286 | |
287 template <typename Terminal> | |
288 result_type operator()(Terminal const& term, unused_type) const | |
289 { | |
290 return result_type(fusion::at_c<0>(term.args)); | |
291 } | |
292 }; | |
293 } | |
294 | |
295 // string("..."), lit("...") | |
296 template <typename CharEncoding, typename Modifiers, typename A0> | |
297 struct make_primitive< | |
298 terminal_ex< | |
299 tag::char_code<tag::string, CharEncoding> | |
300 , fusion::vector1<A0> > | |
301 , Modifiers> | |
302 : detail::make_string_direct<CharEncoding, Modifiers, A0, false> | |
303 {}; | |
304 | |
305 template <typename Modifiers, typename A0> | |
306 struct make_primitive< | |
307 terminal_ex<tag::lit, fusion::vector1<A0> > | |
308 , Modifiers | |
309 , typename enable_if<traits::is_string<A0> >::type> | |
310 : detail::make_string_direct< | |
311 typename traits::char_encoding_from_char< | |
312 typename traits::char_type_of<A0>::type>::type | |
313 , Modifiers, A0, true> | |
314 {}; | |
315 }}} // namespace boost::spirit::karma | |
316 | |
317 namespace boost { namespace spirit { namespace traits | |
318 { | |
319 /////////////////////////////////////////////////////////////////////////// | |
320 template <typename CharEncoding, typename Tag, typename Attribute | |
321 , typename Context, typename Iterator> | |
322 struct handles_container<karma::any_string<CharEncoding, Tag>, Attribute | |
323 , Context, Iterator> | |
324 : mpl::false_ {}; | |
325 | |
326 template <typename String, typename CharEncoding, typename Tag | |
327 , bool no_attribute, typename Attribute, typename Context | |
328 , typename Iterator> | |
329 struct handles_container<karma::literal_string<String, CharEncoding, Tag | |
330 , no_attribute>, Attribute, Context, Iterator> | |
331 : mpl::false_ {}; | |
332 }}} | |
333 | |
334 #endif |