]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/include/boost/spirit/home/karma/numeric/bool.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / karma / numeric / bool.hpp
CommitLineData
7c673cae
FG
1// Copyright (c) 2001-2011 Hartmut Kaiser
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#if !defined(BOOST_SPIRIT_KARMA_BOOL_SEP_28_2009_1113AM)
7#define BOOST_SPIRIT_KARMA_BOOL_SEP_28_2009_1113AM
8
9#if defined(_MSC_VER)
10#pragma once
11#endif
12
13#include <boost/limits.hpp>
14#include <boost/mpl/bool.hpp>
15#include <boost/utility/enable_if.hpp>
16
17#include <boost/spirit/home/support/common_terminals.hpp>
18#include <boost/spirit/home/support/string_traits.hpp>
19#include <boost/spirit/home/support/numeric_traits.hpp>
20#include <boost/spirit/home/support/info.hpp>
21#include <boost/spirit/home/support/char_class.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/enable_lit.hpp>
28#include <boost/spirit/home/karma/domain.hpp>
29#include <boost/spirit/home/karma/numeric/bool_policies.hpp>
30#include <boost/spirit/home/karma/numeric/detail/bool_utils.hpp>
31
32///////////////////////////////////////////////////////////////////////////////
33namespace boost { namespace spirit
34{
35 namespace karma
36 {
37 ///////////////////////////////////////////////////////////////////////
38 // forward declaration only
39 template <typename T>
40 struct bool_policies;
41
42 ///////////////////////////////////////////////////////////////////////
43 // This is the class that the user can instantiate directly in
44 // order to create a customized bool generator
45 template <typename T = bool, typename Policies = bool_policies<T> >
46 struct bool_generator
47 : spirit::terminal<tag::stateful_tag<Policies, tag::bool_, T> >
48 {
49 typedef tag::stateful_tag<Policies, tag::bool_, T> tag_type;
50
51 bool_generator() {}
52 bool_generator(Policies const& data)
53 : spirit::terminal<tag_type>(data) {}
54 };
55 }
56
57 ///////////////////////////////////////////////////////////////////////////
58 // Enablers
59 ///////////////////////////////////////////////////////////////////////////
60 template <>
61 struct use_terminal<karma::domain, tag::bool_> // enables bool_
62 : mpl::true_ {};
63
64 template <>
65 struct use_terminal<karma::domain, tag::true_> // enables true_
66 : mpl::true_ {};
67
68 template <>
69 struct use_terminal<karma::domain, tag::false_> // enables false_
70 : mpl::true_ {};
71
72 template <>
73 struct use_terminal<karma::domain, bool> // enables lit(true)
74 : mpl::true_ {};
75
76 template <typename A0>
77 struct use_terminal<karma::domain // enables bool_(...)
78 , terminal_ex<tag::bool_, fusion::vector1<A0> >
79 > : mpl::true_ {};
80
81 template <> // enables *lazy* bool_(...)
82 struct use_lazy_terminal<karma::domain, tag::bool_, 1>
83 : mpl::true_ {};
84
85 ///////////////////////////////////////////////////////////////////////////
86 // enables any custom bool_generator
87 template <typename Policies, typename T>
88 struct use_terminal<karma::domain
89 , tag::stateful_tag<Policies, tag::bool_, T> >
90 : mpl::true_ {};
91
92 // enables any custom bool_generator(...)
93 template <typename Policies, typename T, typename A0>
94 struct use_terminal<karma::domain
95 , terminal_ex<tag::stateful_tag<Policies, tag::bool_, T>
96 , fusion::vector1<A0> > >
97 : mpl::true_ {};
98
99 // enables *lazy* custom bool_generator
100 template <typename Policies, typename T>
101 struct use_lazy_terminal<karma::domain
102 , tag::stateful_tag<Policies, tag::bool_, T>, 1>
103 : mpl::true_ {};
104
105 // enables lit(bool)
106 template <typename A0>
107 struct use_terminal<karma::domain
108 , terminal_ex<tag::lit, fusion::vector1<A0> >
109 , typename enable_if<traits::is_bool<A0> >::type>
110 : mpl::true_ {};
111}}
112
113///////////////////////////////////////////////////////////////////////////////
114namespace boost { namespace spirit { namespace karma
115{
116#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
117 using spirit::bool_;
118 using spirit::true_;
119 using spirit::false_;
120 using spirit::lit; // lit(true) is equivalent to true
121#endif
122
123 using spirit::bool_type;
124 using spirit::true_type;
125 using spirit::false_type;
126 using spirit::lit_type;
127
128 ///////////////////////////////////////////////////////////////////////////
129 // This specialization is used for bool generators not having a direct
130 // initializer: bool_. These generators must be used in conjunction with
131 // an Attribute.
132 ///////////////////////////////////////////////////////////////////////////
133 template <typename T, typename CharEncoding, typename Tag, typename Policies>
134 struct any_bool_generator
135 : primitive_generator<any_bool_generator<T, CharEncoding, Tag, Policies> >
136 {
137 public:
138 any_bool_generator(Policies const& p = Policies())
139 : p_(p) {}
140
141 typedef typename Policies::properties properties;
142
143 template <typename Context, typename Unused>
144 struct attribute
145 {
146 typedef T type;
147 };
148
149 // bool_ has a Attribute attached
150 template <typename OutputIterator, typename Context, typename Delimiter
151 , typename Attribute>
152 bool
153 generate(OutputIterator& sink, Context& context, Delimiter const& d
154 , Attribute const& attr) const
155 {
156 if (!traits::has_optional_value(attr))
157 return false; // fail if it's an uninitialized optional
158
159 return bool_inserter<T, Policies, CharEncoding, Tag>::call(
160 sink, traits::extract_from<T>(attr, context), p_) &&
161 delimit_out(sink, d); // always do post-delimiting
162 }
163
164 // this bool_ has no Attribute attached, it needs to have been
165 // initialized from a direct literal
166 template <typename OutputIterator, typename Context, typename Delimiter>
167 static bool
168 generate(OutputIterator&, Context&, Delimiter const&, unused_type)
169 {
170 // It is not possible (doesn't make sense) to use boolean generators
171 // without providing any attribute, as the generator doesn't 'know'
172 // what to output. The following assertion fires if this situation
173 // is detected in your code.
174 BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, bool_not_usable_without_attribute, ());
175 return false;
176 }
177
178 template <typename Context>
179 static info what(Context const& /*context*/)
180 {
181 return info("bool");
182 }
183
184 Policies p_;
185 };
186
187 ///////////////////////////////////////////////////////////////////////////
188 // This specialization is used for bool generators having a direct
189 // initializer: bool_(true), bool_(0) etc.
190 ///////////////////////////////////////////////////////////////////////////
191 template <typename T, typename CharEncoding, typename Tag
192 , typename Policies, bool no_attribute>
193 struct literal_bool_generator
194 : primitive_generator<literal_bool_generator<T, CharEncoding, Tag
195 , Policies, no_attribute> >
196 {
197 public:
198 typedef typename Policies::properties properties;
199
200 template <typename Context, typename Unused = unused_type>
201 struct attribute
202 : mpl::if_c<no_attribute, unused_type, T>
203 {};
204
205 literal_bool_generator(typename add_const<T>::type n
206 , Policies const& p = Policies())
207 : n_(n), p_(p) {}
208
209 // A bool_() which additionally has an associated attribute emits
210 // its immediate literal only if it matches the attribute, otherwise
211 // it fails.
212 template <typename OutputIterator, typename Context, typename Delimiter
213 , typename Attribute>
214 bool generate(OutputIterator& sink, Context& context
215 , Delimiter const& d, Attribute const& attr) const
216 {
217 typedef typename attribute<Context>::type attribute_type;
218 if (!traits::has_optional_value(attr) ||
219 bool(n_) != bool(traits::extract_from<attribute_type>(attr, context)))
220 {
221 return false;
222 }
223 return bool_inserter<T, Policies, CharEncoding, Tag>::
224 call(sink, n_, p_) && delimit_out(sink, d);
225 }
226
227 // A bool_() without any associated attribute just emits its
228 // immediate literal
229 template <typename OutputIterator, typename Context, typename Delimiter>
230 bool generate(OutputIterator& sink, Context&, Delimiter const& d
231 , unused_type) const
232 {
233 return bool_inserter<T, Policies, CharEncoding, Tag>::
234 call(sink, n_) && delimit_out(sink, d);
235 }
236
237 template <typename Context>
238 static info what(Context const& /*context*/)
239 {
240 return info("bool");
241 }
242
243 T n_;
244 Policies p_;
245 };
246
247 ///////////////////////////////////////////////////////////////////////////
248 // Generator generators: make_xxx function (objects)
249 ///////////////////////////////////////////////////////////////////////////
250 namespace detail
251 {
252 template <typename Modifiers, typename T = bool
253 , typename Policies = bool_policies<T> >
254 struct make_bool
255 {
256 static bool const lower =
257 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
258 static bool const upper =
259 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
260
261 typedef any_bool_generator<
262 T
263 , typename spirit::detail::get_encoding_with_case<
264 Modifiers, unused_type, lower || upper>::type
265 , typename detail::get_casetag<Modifiers, lower || upper>::type
266 , Policies
267 > result_type;
268
269 template <typename Terminal>
270 result_type operator()(Terminal const& term, unused_type) const
271 {
272 typedef tag::stateful_tag<Policies, tag::bool_, T> tag_type;
273 using spirit::detail::get_stateful_data;
274 return result_type(get_stateful_data<tag_type>::call(term));
275 }
276 };
277
278 template <typename Modifiers, bool b>
279 struct make_bool_literal
280 {
281 static bool const lower =
282 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
283 static bool const upper =
284 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
285
286 typedef literal_bool_generator<
287 bool
288 , typename spirit::detail::get_encoding_with_case<
289 Modifiers, unused_type, lower || upper>::type
290 , typename detail::get_casetag<Modifiers, lower || upper>::type
291 , bool_policies<>, false
292 > result_type;
293
294 result_type operator()(unused_type, unused_type) const
295 {
296 return result_type(b);
297 }
298 };
299 }
300
301 ///////////////////////////////////////////////////////////////////////////
302 template <typename Modifiers>
303 struct make_primitive<tag::bool_, Modifiers>
304 : detail::make_bool<Modifiers> {};
305
306 template <typename Modifiers>
307 struct make_primitive<tag::true_, Modifiers>
308 : detail::make_bool_literal<Modifiers, true> {};
309
310 template <typename Modifiers>
311 struct make_primitive<tag::false_, Modifiers>
312 : detail::make_bool_literal<Modifiers, false> {};
313
314 template <typename T, typename Policies, typename Modifiers>
315 struct make_primitive<
316 tag::stateful_tag<Policies, tag::bool_, T>, Modifiers>
317 : detail::make_bool<Modifiers
318 , typename remove_const<T>::type, Policies> {};
319
320 ///////////////////////////////////////////////////////////////////////////
321 namespace detail
322 {
323 template <typename Modifiers, typename T = bool
324 , typename Policies = bool_policies<T> >
325 struct make_bool_direct
326 {
327 static bool const lower =
328 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
329 static bool const upper =
330 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
331
332 typedef literal_bool_generator<
333 T
334 , typename spirit::detail::get_encoding_with_case<
335 Modifiers, unused_type, lower || upper>::type
336 , typename detail::get_casetag<Modifiers, lower || upper>::type
337 , Policies, false
338 > result_type;
339
340 template <typename Terminal>
341 result_type operator()(Terminal const& term, unused_type) const
342 {
343 typedef tag::stateful_tag<Policies, tag::bool_, T> tag_type;
344 using spirit::detail::get_stateful_data;
345 return result_type(fusion::at_c<0>(term.args)
346 , get_stateful_data<tag_type>::call(term.term));
347 }
348 };
349 }
350
351 ///////////////////////////////////////////////////////////////////////////
352 template <typename Modifiers, typename A0>
353 struct make_primitive<
354 terminal_ex<tag::bool_, fusion::vector1<A0> >, Modifiers>
355 : detail::make_bool_direct<Modifiers> {};
356
357 template <typename T, typename Policies, typename A0, typename Modifiers>
358 struct make_primitive<
359 terminal_ex<tag::stateful_tag<Policies, tag::bool_, T>
360 , fusion::vector1<A0> >
361 , Modifiers>
362 : detail::make_bool_direct<Modifiers
363 , typename remove_const<T>::type, Policies> {};
364
365 ///////////////////////////////////////////////////////////////////////////
366 namespace detail
367 {
368 template <typename Modifiers>
369 struct basic_bool_literal
370 {
371 static bool const lower =
372 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
373 static bool const upper =
374 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
375
376 typedef literal_bool_generator<
377 bool
378 , typename spirit::detail::get_encoding_with_case<
379 Modifiers, unused_type, lower || upper>::type
380 , typename detail::get_casetag<Modifiers, lower || upper>::type
381 , bool_policies<>, true
382 > result_type;
383
384 template <typename T_>
385 result_type operator()(T_ i, unused_type) const
386 {
387 return result_type(i);
388 }
389 };
390 }
391
392 template <typename Modifiers>
393 struct make_primitive<bool, Modifiers>
394 : detail::basic_bool_literal<Modifiers> {};
395
396 template <typename Modifiers, typename A0>
397 struct make_primitive<
398 terminal_ex<tag::lit, fusion::vector1<A0> >
399 , Modifiers
400 , typename enable_if<traits::is_bool<A0> >::type>
401 : detail::basic_bool_literal<Modifiers>
402 {
403 static bool const lower =
404 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
405 static bool const upper =
406 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
407
408 typedef literal_bool_generator<
409 bool
410 , typename spirit::detail::get_encoding_with_case<
411 Modifiers, unused_type, lower || upper>::type
412 , typename detail::get_casetag<Modifiers, lower || upper>::type
413 , bool_policies<>, true
414 > result_type;
415
416 template <typename Terminal>
417 result_type operator()(Terminal const& term, unused_type) const
418 {
419 return result_type(fusion::at_c<0>(term.args));
420 }
421 };
422}}}
423
424#endif