File indexing completed on 2025-01-19 09:47:38
0001
0002
0003
0004
0005
0006 #if !defined(BOOST_SPIRIT_KARMA_BOOL_SEP_28_2009_1113AM)
0007 #define BOOST_SPIRIT_KARMA_BOOL_SEP_28_2009_1113AM
0008
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012
0013 #include <boost/limits.hpp>
0014 #include <boost/mpl/bool.hpp>
0015 #include <boost/utility/enable_if.hpp>
0016
0017 #include <boost/spirit/home/support/common_terminals.hpp>
0018 #include <boost/spirit/home/support/string_traits.hpp>
0019 #include <boost/spirit/home/support/numeric_traits.hpp>
0020 #include <boost/spirit/home/support/info.hpp>
0021 #include <boost/spirit/home/support/char_class.hpp>
0022 #include <boost/spirit/home/karma/meta_compiler.hpp>
0023 #include <boost/spirit/home/karma/delimit_out.hpp>
0024 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
0025 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
0026 #include <boost/spirit/home/karma/detail/extract_from.hpp>
0027 #include <boost/spirit/home/karma/detail/enable_lit.hpp>
0028 #include <boost/spirit/home/karma/domain.hpp>
0029 #include <boost/spirit/home/karma/numeric/bool_policies.hpp>
0030 #include <boost/spirit/home/karma/numeric/detail/bool_utils.hpp>
0031
0032
0033 namespace boost { namespace spirit
0034 {
0035 namespace karma
0036 {
0037
0038
0039 template <typename T>
0040 struct bool_policies;
0041
0042
0043
0044
0045 template <typename T = bool, typename Policies = bool_policies<T> >
0046 struct bool_generator
0047 : spirit::terminal<tag::stateful_tag<Policies, tag::bool_, T> >
0048 {
0049 typedef tag::stateful_tag<Policies, tag::bool_, T> tag_type;
0050
0051 bool_generator() {}
0052 bool_generator(Policies const& data)
0053 : spirit::terminal<tag_type>(data) {}
0054 };
0055 }
0056
0057
0058
0059
0060 template <>
0061 struct use_terminal<karma::domain, tag::bool_>
0062 : mpl::true_ {};
0063
0064 template <>
0065 struct use_terminal<karma::domain, tag::true_>
0066 : mpl::true_ {};
0067
0068 template <>
0069 struct use_terminal<karma::domain, tag::false_>
0070 : mpl::true_ {};
0071
0072 template <>
0073 struct use_terminal<karma::domain, bool>
0074 : mpl::true_ {};
0075
0076 template <typename A0>
0077 struct use_terminal<karma::domain
0078 , terminal_ex<tag::bool_, fusion::vector1<A0> >
0079 > : mpl::true_ {};
0080
0081 template <>
0082 struct use_lazy_terminal<karma::domain, tag::bool_, 1>
0083 : mpl::true_ {};
0084
0085
0086
0087 template <typename Policies, typename T>
0088 struct use_terminal<karma::domain
0089 , tag::stateful_tag<Policies, tag::bool_, T> >
0090 : mpl::true_ {};
0091
0092
0093 template <typename Policies, typename T, typename A0>
0094 struct use_terminal<karma::domain
0095 , terminal_ex<tag::stateful_tag<Policies, tag::bool_, T>
0096 , fusion::vector1<A0> > >
0097 : mpl::true_ {};
0098
0099
0100 template <typename Policies, typename T>
0101 struct use_lazy_terminal<karma::domain
0102 , tag::stateful_tag<Policies, tag::bool_, T>, 1>
0103 : mpl::true_ {};
0104
0105
0106 template <typename A0>
0107 struct use_terminal<karma::domain
0108 , terminal_ex<tag::lit, fusion::vector1<A0> >
0109 , typename enable_if<traits::is_bool<A0> >::type>
0110 : mpl::true_ {};
0111 }}
0112
0113
0114 namespace boost { namespace spirit { namespace karma
0115 {
0116 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0117 using spirit::bool_;
0118 using spirit::true_;
0119 using spirit::false_;
0120 using spirit::lit;
0121 #endif
0122
0123 using spirit::bool_type;
0124 using spirit::true_type;
0125 using spirit::false_type;
0126 using spirit::lit_type;
0127
0128
0129
0130
0131
0132
0133 template <typename T, typename CharEncoding, typename Tag, typename Policies>
0134 struct any_bool_generator
0135 : primitive_generator<any_bool_generator<T, CharEncoding, Tag, Policies> >
0136 {
0137 public:
0138 any_bool_generator(Policies const& p = Policies())
0139 : p_(p) {}
0140
0141 typedef typename Policies::properties properties;
0142
0143 template <typename Context, typename Unused>
0144 struct attribute
0145 {
0146 typedef T type;
0147 };
0148
0149
0150 template <typename OutputIterator, typename Context, typename Delimiter
0151 , typename Attribute>
0152 bool
0153 generate(OutputIterator& sink, Context& context, Delimiter const& d
0154 , Attribute const& attr) const
0155 {
0156 if (!traits::has_optional_value(attr))
0157 return false;
0158
0159 return bool_inserter<T, Policies, CharEncoding, Tag>::call(
0160 sink, traits::extract_from<T>(attr, context), p_) &&
0161 delimit_out(sink, d);
0162 }
0163
0164
0165
0166 template <typename OutputIterator, typename Context, typename Delimiter>
0167 static bool
0168 generate(OutputIterator&, Context&, Delimiter const&, unused_type)
0169 {
0170
0171
0172
0173
0174 BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, bool_not_usable_without_attribute, ());
0175 return false;
0176 }
0177
0178 template <typename Context>
0179 static info what(Context const& )
0180 {
0181 return info("bool");
0182 }
0183
0184 Policies p_;
0185 };
0186
0187
0188
0189
0190
0191 template <typename T, typename CharEncoding, typename Tag
0192 , typename Policies, bool no_attribute>
0193 struct literal_bool_generator
0194 : primitive_generator<literal_bool_generator<T, CharEncoding, Tag
0195 , Policies, no_attribute> >
0196 {
0197 public:
0198 typedef typename Policies::properties properties;
0199
0200 template <typename Context, typename Unused = unused_type>
0201 struct attribute
0202 : mpl::if_c<no_attribute, unused_type, T>
0203 {};
0204
0205 literal_bool_generator(typename add_const<T>::type n
0206 , Policies const& p = Policies())
0207 : n_(n), p_(p) {}
0208
0209
0210
0211
0212 template <typename OutputIterator, typename Context, typename Delimiter
0213 , typename Attribute>
0214 bool generate(OutputIterator& sink, Context& context
0215 , Delimiter const& d, Attribute const& attr) const
0216 {
0217 typedef typename attribute<Context>::type attribute_type;
0218 if (!traits::has_optional_value(attr) ||
0219 bool(n_) != bool(traits::extract_from<attribute_type>(attr, context)))
0220 {
0221 return false;
0222 }
0223 return bool_inserter<T, Policies, CharEncoding, Tag>::
0224 call(sink, n_, p_) && delimit_out(sink, d);
0225 }
0226
0227
0228
0229 template <typename OutputIterator, typename Context, typename Delimiter>
0230 bool generate(OutputIterator& sink, Context&, Delimiter const& d
0231 , unused_type) const
0232 {
0233 return bool_inserter<T, Policies, CharEncoding, Tag>::
0234 call(sink, n_) && delimit_out(sink, d);
0235 }
0236
0237 template <typename Context>
0238 static info what(Context const& )
0239 {
0240 return info("bool");
0241 }
0242
0243 T n_;
0244 Policies p_;
0245 };
0246
0247
0248
0249
0250 namespace detail
0251 {
0252 template <typename Modifiers, typename T = bool
0253 , typename Policies = bool_policies<T> >
0254 struct make_bool
0255 {
0256 static bool const lower =
0257 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0258 static bool const upper =
0259 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0260
0261 typedef any_bool_generator<
0262 T
0263 , typename spirit::detail::get_encoding_with_case<
0264 Modifiers, unused_type, lower || upper>::type
0265 , typename detail::get_casetag<Modifiers, lower || upper>::type
0266 , Policies
0267 > result_type;
0268
0269 template <typename Terminal>
0270 result_type operator()(Terminal const& term, unused_type) const
0271 {
0272 typedef tag::stateful_tag<Policies, tag::bool_, T> tag_type;
0273 using spirit::detail::get_stateful_data;
0274 return result_type(get_stateful_data<tag_type>::call(term));
0275 }
0276 };
0277
0278 template <typename Modifiers, bool b>
0279 struct make_bool_literal
0280 {
0281 static bool const lower =
0282 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0283 static bool const upper =
0284 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0285
0286 typedef literal_bool_generator<
0287 bool
0288 , typename spirit::detail::get_encoding_with_case<
0289 Modifiers, unused_type, lower || upper>::type
0290 , typename detail::get_casetag<Modifiers, lower || upper>::type
0291 , bool_policies<>, false
0292 > result_type;
0293
0294 result_type operator()(unused_type, unused_type) const
0295 {
0296 return result_type(b);
0297 }
0298 };
0299 }
0300
0301
0302 template <typename Modifiers>
0303 struct make_primitive<tag::bool_, Modifiers>
0304 : detail::make_bool<Modifiers> {};
0305
0306 template <typename Modifiers>
0307 struct make_primitive<tag::true_, Modifiers>
0308 : detail::make_bool_literal<Modifiers, true> {};
0309
0310 template <typename Modifiers>
0311 struct make_primitive<tag::false_, Modifiers>
0312 : detail::make_bool_literal<Modifiers, false> {};
0313
0314 template <typename T, typename Policies, typename Modifiers>
0315 struct make_primitive<
0316 tag::stateful_tag<Policies, tag::bool_, T>, Modifiers>
0317 : detail::make_bool<Modifiers
0318 , typename remove_const<T>::type, Policies> {};
0319
0320
0321 namespace detail
0322 {
0323 template <typename Modifiers, typename T = bool
0324 , typename Policies = bool_policies<T> >
0325 struct make_bool_direct
0326 {
0327 static bool const lower =
0328 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0329 static bool const upper =
0330 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0331
0332 typedef literal_bool_generator<
0333 T
0334 , typename spirit::detail::get_encoding_with_case<
0335 Modifiers, unused_type, lower || upper>::type
0336 , typename detail::get_casetag<Modifiers, lower || upper>::type
0337 , Policies, false
0338 > result_type;
0339
0340 template <typename Terminal>
0341 result_type operator()(Terminal const& term, unused_type) const
0342 {
0343 typedef tag::stateful_tag<Policies, tag::bool_, T> tag_type;
0344 using spirit::detail::get_stateful_data;
0345 return result_type(fusion::at_c<0>(term.args)
0346 , get_stateful_data<tag_type>::call(term.term));
0347 }
0348 };
0349 }
0350
0351
0352 template <typename Modifiers, typename A0>
0353 struct make_primitive<
0354 terminal_ex<tag::bool_, fusion::vector1<A0> >, Modifiers>
0355 : detail::make_bool_direct<Modifiers> {};
0356
0357 template <typename T, typename Policies, typename A0, typename Modifiers>
0358 struct make_primitive<
0359 terminal_ex<tag::stateful_tag<Policies, tag::bool_, T>
0360 , fusion::vector1<A0> >
0361 , Modifiers>
0362 : detail::make_bool_direct<Modifiers
0363 , typename remove_const<T>::type, Policies> {};
0364
0365
0366 namespace detail
0367 {
0368 template <typename Modifiers>
0369 struct basic_bool_literal
0370 {
0371 static bool const lower =
0372 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0373 static bool const upper =
0374 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0375
0376 typedef literal_bool_generator<
0377 bool
0378 , typename spirit::detail::get_encoding_with_case<
0379 Modifiers, unused_type, lower || upper>::type
0380 , typename detail::get_casetag<Modifiers, lower || upper>::type
0381 , bool_policies<>, true
0382 > result_type;
0383
0384 template <typename T_>
0385 result_type operator()(T_ i, unused_type) const
0386 {
0387 return result_type(i);
0388 }
0389 };
0390 }
0391
0392 template <typename Modifiers>
0393 struct make_primitive<bool, Modifiers>
0394 : detail::basic_bool_literal<Modifiers> {};
0395
0396 template <typename Modifiers, typename A0>
0397 struct make_primitive<
0398 terminal_ex<tag::lit, fusion::vector1<A0> >
0399 , Modifiers
0400 , typename enable_if<traits::is_bool<A0> >::type>
0401 : detail::basic_bool_literal<Modifiers>
0402 {
0403 static bool const lower =
0404 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0405 static bool const upper =
0406 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0407
0408 typedef literal_bool_generator<
0409 bool
0410 , typename spirit::detail::get_encoding_with_case<
0411 Modifiers, unused_type, lower || upper>::type
0412 , typename detail::get_casetag<Modifiers, lower || upper>::type
0413 , bool_policies<>, true
0414 > result_type;
0415
0416 template <typename Terminal>
0417 result_type operator()(Terminal const& term, unused_type) const
0418 {
0419 return result_type(fusion::at_c<0>(term.args));
0420 }
0421 };
0422 }}}
0423
0424 #endif