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