File indexing completed on 2025-01-19 09:47:46
0001
0002
0003
0004
0005
0006
0007
0008 #if !defined(BOOST_SPIRIT_REAL_APRIL_18_2006_0850AM)
0009 #define BOOST_SPIRIT_REAL_APRIL_18_2006_0850AM
0010
0011 #if defined(_MSC_VER)
0012 #pragma once
0013 #endif
0014
0015 #include <boost/spirit/home/qi/skip_over.hpp>
0016 #include <boost/spirit/home/qi/detail/enable_lit.hpp>
0017 #include <boost/spirit/home/qi/meta_compiler.hpp>
0018 #include <boost/spirit/home/qi/parser.hpp>
0019 #include <boost/spirit/home/qi/numeric/real_policies.hpp>
0020 #include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
0021 #include <boost/spirit/home/qi/numeric/detail/real_impl.hpp>
0022 #include <boost/spirit/home/support/common_terminals.hpp>
0023 #include <boost/type_traits/is_same.hpp>
0024
0025 namespace boost { namespace spirit
0026 {
0027 namespace qi
0028 {
0029
0030
0031 template <typename T>
0032 struct real_policies;
0033
0034
0035
0036
0037 template <typename T = double, typename Policies = real_policies<T> >
0038 struct real_parser
0039 : spirit::terminal<tag::stateful_tag<Policies, tag::double_, T> >
0040 {
0041 typedef tag::stateful_tag<Policies, tag::double_, T> tag_type;
0042
0043 real_parser() {}
0044 real_parser(Policies const& p)
0045 : spirit::terminal<tag_type>(p) {}
0046 };
0047 }
0048
0049
0050
0051
0052 template <>
0053 struct use_terminal<qi::domain, tag::float_>
0054 : mpl::true_ {};
0055
0056 template <>
0057 struct use_terminal<qi::domain, tag::double_>
0058 : mpl::true_ {};
0059
0060 template <>
0061 struct use_terminal<qi::domain, tag::long_double>
0062 : mpl::true_ {};
0063
0064
0065 template <typename A0>
0066 struct use_terminal<qi::domain
0067 , terminal_ex<tag::lit, fusion::vector1<A0> >
0068 , typename enable_if<is_same<A0, float> >::type>
0069 : mpl::true_ {};
0070
0071 template <typename A0>
0072 struct use_terminal<qi::domain
0073 , terminal_ex<tag::lit, fusion::vector1<A0> >
0074 , typename enable_if<is_same<A0, double> >::type>
0075 : mpl::true_ {};
0076
0077 template <typename A0>
0078 struct use_terminal<qi::domain
0079 , terminal_ex<tag::lit, fusion::vector1<A0> >
0080 , typename enable_if<is_same<A0, long double> >::type>
0081 : mpl::true_ {};
0082
0083
0084 template <typename A0>
0085 struct use_terminal<qi::domain
0086 , terminal_ex<tag::float_, fusion::vector1<A0> >
0087 > : mpl::true_ {};
0088
0089 template <typename A0>
0090 struct use_terminal<qi::domain
0091 , terminal_ex<tag::double_, fusion::vector1<A0> >
0092 > : mpl::true_ {};
0093
0094 template <typename A0>
0095 struct use_terminal<qi::domain
0096 , terminal_ex<tag::long_double, fusion::vector1<A0> >
0097 > : mpl::true_ {};
0098
0099 template <>
0100 struct use_lazy_terminal<qi::domain, tag::float_, 1>
0101 : mpl::true_ {};
0102
0103 template <>
0104 struct use_lazy_terminal<qi::domain, tag::double_, 1>
0105 : mpl::true_ {};
0106
0107 template <>
0108 struct use_lazy_terminal<qi::domain, tag::long_double, 1>
0109 : mpl::true_ {};
0110
0111
0112
0113 template <typename T, typename Policies>
0114 struct use_terminal<qi::domain
0115 , tag::stateful_tag<Policies, tag::double_, T> >
0116 : mpl::true_ {};
0117
0118
0119 template <typename T, typename Policies, typename A0>
0120 struct use_terminal<qi::domain
0121 , terminal_ex<tag::stateful_tag<Policies, tag::double_, T>
0122 , fusion::vector1<A0> > >
0123 : mpl::true_ {};
0124
0125
0126 template <typename T, typename Policies>
0127 struct use_lazy_terminal<
0128 qi::domain
0129 , tag::stateful_tag<Policies, tag::double_, T>
0130 , 1
0131 > : mpl::true_ {};
0132 }}
0133
0134 namespace boost { namespace spirit { namespace qi
0135 {
0136 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0137 using spirit::float_;
0138 using spirit::double_;
0139 using spirit::long_double;
0140 using spirit::lit;
0141 #endif
0142
0143 using spirit::float_type;
0144 using spirit::double_type;
0145 using spirit::long_double_type;
0146 using spirit::lit_type;
0147
0148
0149
0150
0151 template <typename T, typename RealPolicies = real_policies<T> >
0152 struct any_real_parser
0153 : primitive_parser<any_real_parser<T, RealPolicies> >
0154 {
0155 template <typename Context, typename Iterator>
0156 struct attribute
0157 {
0158 typedef T type;
0159 };
0160
0161 template <typename Iterator, typename Context, typename Skipper>
0162 bool parse(Iterator& first, Iterator const& last
0163 , Context& , Skipper const& skipper
0164 , T& attr_) const
0165 {
0166 typedef detail::real_impl<T, RealPolicies> extract;
0167 qi::skip_over(first, last, skipper);
0168 return extract::parse(first, last, attr_, RealPolicies());
0169 }
0170
0171 template <typename Iterator, typename Context
0172 , typename Skipper, typename Attribute>
0173 bool parse(Iterator& first, Iterator const& last
0174 , Context& context, Skipper const& skipper
0175 , Attribute& attr_param) const
0176 {
0177
0178 T attr_;
0179 if (parse(first, last, context, skipper, attr_))
0180 {
0181 traits::assign_to(attr_, attr_param);
0182 return true;
0183 }
0184 return false;
0185 }
0186
0187 template <typename Context>
0188 info what(Context& ) const
0189 {
0190 return info("real");
0191 }
0192 };
0193
0194 template <typename T, typename RealPolicies = real_policies<T>
0195 , bool no_attribute = true>
0196 struct literal_real_parser
0197 : primitive_parser<literal_real_parser<T, RealPolicies, no_attribute> >
0198 {
0199 template <typename Value>
0200 literal_real_parser(Value const& n) : n_(n) {}
0201
0202 template <typename Context, typename Iterator>
0203 struct attribute
0204 : mpl::if_c<no_attribute, unused_type, T>
0205 {};
0206
0207 template <typename Iterator, typename Context
0208 , typename Skipper, typename Attribute>
0209 bool parse(Iterator& first, Iterator const& last
0210 , Context&, Skipper const& skipper
0211 , Attribute& attr_param) const
0212 {
0213 typedef detail::real_impl<T, RealPolicies> extract;
0214 qi::skip_over(first, last, skipper);
0215
0216 Iterator save = first;
0217 T attr_;
0218
0219 if (extract::parse(first, last, attr_, RealPolicies()) &&
0220 (attr_ == n_))
0221 {
0222 traits::assign_to(attr_, attr_param);
0223 return true;
0224 }
0225
0226 first = save;
0227 return false;
0228 }
0229
0230 template <typename Context>
0231 info what(Context& ) const
0232 {
0233 return info("real");
0234 }
0235
0236 T n_;
0237 };
0238
0239
0240
0241
0242 template <typename T, typename Policies = real_policies<T> >
0243 struct make_real
0244 {
0245 typedef any_real_parser<T, Policies> result_type;
0246
0247 result_type operator()(unused_type, unused_type) const
0248 {
0249 return result_type();
0250 }
0251 };
0252
0253 template <typename T, typename Policies = real_policies<T> >
0254 struct make_direct_real
0255 {
0256 typedef literal_real_parser<T, Policies, false> result_type;
0257
0258 template <typename Terminal>
0259 result_type operator()(Terminal const& term, unused_type) const
0260 {
0261 return result_type(T(fusion::at_c<0>(term.args)));
0262 }
0263 };
0264
0265 template <typename T, typename Policies = real_policies<T> >
0266 struct make_literal_real
0267 {
0268 typedef literal_real_parser<T, Policies> result_type;
0269
0270 template <typename Terminal>
0271 result_type operator()(Terminal const& term, unused_type) const
0272 {
0273 return result_type(fusion::at_c<0>(term.args));
0274 }
0275 };
0276
0277
0278 template <typename Modifiers, typename A0>
0279 struct make_primitive<
0280 terminal_ex<tag::lit, fusion::vector1<A0> >
0281 , Modifiers, typename enable_if<is_same<A0, float> >::type>
0282 : make_literal_real<float> {};
0283
0284 template <typename Modifiers, typename A0>
0285 struct make_primitive<
0286 terminal_ex<tag::lit, fusion::vector1<A0> >
0287 , Modifiers, typename enable_if<is_same<A0, double> >::type>
0288 : make_literal_real<double> {};
0289
0290 template <typename Modifiers, typename A0>
0291 struct make_primitive<
0292 terminal_ex<tag::lit, fusion::vector1<A0> >
0293 , Modifiers, typename enable_if<is_same<A0, long double> >::type>
0294 : make_literal_real<long double> {};
0295
0296
0297 template <typename T, typename Policies, typename Modifiers>
0298 struct make_primitive<
0299 tag::stateful_tag<Policies, tag::double_, T>, Modifiers>
0300 : make_real<T, Policies> {};
0301
0302 template <typename T, typename Policies, typename A0, typename Modifiers>
0303 struct make_primitive<
0304 terminal_ex<tag::stateful_tag<Policies, tag::double_, T>
0305 , fusion::vector1<A0> >, Modifiers>
0306 : make_direct_real<T, Policies> {};
0307
0308
0309 template <typename Modifiers>
0310 struct make_primitive<tag::float_, Modifiers>
0311 : make_real<float> {};
0312
0313 template <typename Modifiers, typename A0>
0314 struct make_primitive<
0315 terminal_ex<tag::float_
0316 , fusion::vector1<A0> >, Modifiers>
0317 : make_direct_real<float> {};
0318
0319
0320 template <typename Modifiers>
0321 struct make_primitive<tag::double_, Modifiers>
0322 : make_real<double> {};
0323
0324 template <typename Modifiers, typename A0>
0325 struct make_primitive<
0326 terminal_ex<tag::double_
0327 , fusion::vector1<A0> >, Modifiers>
0328 : make_direct_real<double> {};
0329
0330
0331 template <typename Modifiers>
0332 struct make_primitive<tag::long_double, Modifiers>
0333 : make_real<long double> {};
0334
0335 template <typename Modifiers, typename A0>
0336 struct make_primitive<
0337 terminal_ex<tag::long_double
0338 , fusion::vector1<A0> >, Modifiers>
0339 : make_direct_real<long double> {};
0340 }}}
0341
0342 #endif