/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2011 Bryce Lelbach Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #if !defined(BOOST_SPIRIT_REAL_APRIL_18_2006_0850AM) #define BOOST_SPIRIT_REAL_APRIL_18_2006_0850AM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include #include namespace boost { namespace spirit { namespace qi { /////////////////////////////////////////////////////////////////////// // forward declaration only template struct real_policies; /////////////////////////////////////////////////////////////////////// // This is the class that the user can instantiate directly in // order to create a customized real parser template > struct real_parser : spirit::terminal > { typedef tag::stateful_tag tag_type; real_parser() {} real_parser(Policies const& p) : spirit::terminal(p) {} }; } /////////////////////////////////////////////////////////////////////////// // Enablers /////////////////////////////////////////////////////////////////////////// template <> // enables float_ struct use_terminal : mpl::true_ {}; template <> // enables double_ struct use_terminal : mpl::true_ {}; template <> // enables long_double struct use_terminal : mpl::true_ {}; /////////////////////////////////////////////////////////////////////////// template // enables lit(n) struct use_terminal > , typename enable_if >::type> : mpl::true_ {}; template // enables lit(n) struct use_terminal > , typename enable_if >::type> : mpl::true_ {}; template // enables lit(n) struct use_terminal > , typename enable_if >::type> : mpl::true_ {}; /////////////////////////////////////////////////////////////////////////// template // enables float_(...) struct use_terminal > > : mpl::true_ {}; template // enables double_(...) struct use_terminal > > : mpl::true_ {}; template // enables long_double(...) struct use_terminal > > : mpl::true_ {}; template <> // enables *lazy* float_(...) struct use_lazy_terminal : mpl::true_ {}; template <> // enables *lazy* double_(...) struct use_lazy_terminal : mpl::true_ {}; template <> // enables *lazy* long_double_(...) struct use_lazy_terminal : mpl::true_ {}; /////////////////////////////////////////////////////////////////////////// // enables custom real_parser template struct use_terminal > : mpl::true_ {}; // enables custom real_parser(...) template struct use_terminal , fusion::vector1 > > : mpl::true_ {}; // enables *lazy* custom real_parser(...) template struct use_lazy_terminal< qi::domain , tag::stateful_tag , 1 // arity > : mpl::true_ {}; }} namespace boost { namespace spirit { namespace qi { #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS using spirit::float_; using spirit::double_; using spirit::long_double; using spirit::lit; // lit(1.0) is equivalent to 1.0 #endif using spirit::float_type; using spirit::double_type; using spirit::long_double_type; using spirit::lit_type; /////////////////////////////////////////////////////////////////////////// // This is the actual real number parser /////////////////////////////////////////////////////////////////////////// template > struct any_real_parser : primitive_parser > { template struct attribute { typedef T type; }; template bool parse(Iterator& first, Iterator const& last , Context& /*context*/, Skipper const& skipper , T& attr_) const { typedef detail::real_impl extract; qi::skip_over(first, last, skipper); return extract::parse(first, last, attr_, RealPolicies()); } template bool parse(Iterator& first, Iterator const& last , Context& context, Skipper const& skipper , Attribute& attr_param) const { // this case is called when Attribute is not T T attr_; if (parse(first, last, context, skipper, attr_)) { traits::assign_to(attr_, attr_param); return true; } return false; } template info what(Context& /*context*/) const { return info("real"); } }; template , bool no_attribute = true> struct literal_real_parser : primitive_parser > { template literal_real_parser(Value const& n) : n_(n) {} template struct attribute : mpl::if_c {}; template bool parse(Iterator& first, Iterator const& last , Context&, Skipper const& skipper , Attribute& attr_param) const { typedef detail::real_impl extract; qi::skip_over(first, last, skipper); Iterator save = first; T attr_; if (extract::parse(first, last, attr_, RealPolicies()) && (attr_ == n_)) { traits::assign_to(attr_, attr_param); return true; } first = save; return false; } template info what(Context& /*context*/) const { return info("real"); } T n_; }; /////////////////////////////////////////////////////////////////////////// // Parser generators: make_xxx function (objects) /////////////////////////////////////////////////////////////////////////// template > struct make_real { typedef any_real_parser result_type; result_type operator()(unused_type, unused_type) const { return result_type(); } }; template > struct make_direct_real { typedef literal_real_parser result_type; template result_type operator()(Terminal const& term, unused_type) const { return result_type(T(fusion::at_c<0>(term.args))); } }; template > struct make_literal_real { typedef literal_real_parser result_type; template result_type operator()(Terminal const& term, unused_type) const { return result_type(fusion::at_c<0>(term.args)); } }; /////////////////////////////////////////////////////////////////////////// template struct make_primitive< terminal_ex > , Modifiers, typename enable_if >::type> : make_literal_real {}; template struct make_primitive< terminal_ex > , Modifiers, typename enable_if >::type> : make_literal_real {}; template struct make_primitive< terminal_ex > , Modifiers, typename enable_if >::type> : make_literal_real {}; /////////////////////////////////////////////////////////////////////////// template struct make_primitive< tag::stateful_tag, Modifiers> : make_real {}; template struct make_primitive< terminal_ex , fusion::vector1 >, Modifiers> : make_direct_real {}; /////////////////////////////////////////////////////////////////////////// template struct make_primitive : make_real {}; template struct make_primitive< terminal_ex >, Modifiers> : make_direct_real {}; /////////////////////////////////////////////////////////////////////////// template struct make_primitive : make_real {}; template struct make_primitive< terminal_ex >, Modifiers> : make_direct_real {}; /////////////////////////////////////////////////////////////////////////// template struct make_primitive : make_real {}; template struct make_primitive< terminal_ex >, Modifiers> : make_direct_real {}; }}} #endif