/*============================================================================= Copyright (c) 2001-2007 Joel de Guzman 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_META_GRAMMAR_FEB_05_2007_0951AM) #define BOOST_SPIRIT_META_GRAMMAR_FEB_05_2007_0951AM #include #include #include #include #include namespace boost { namespace spirit { namespace qi { template struct int_tag; template struct uint_tag; template struct real_tag; } template struct is_int_tag, qi::domain> : mpl::true_ {}; template struct is_int_tag, qi::domain> : mpl::true_ {}; template struct is_real_tag, qi::domain> : mpl::true_ {}; }} namespace boost { namespace spirit { namespace qi { /////////////////////////////////////////////////////////////////////////// // forwards /////////////////////////////////////////////////////////////////////////// template struct int_parser; template struct uint_parser; template struct real_parser; template struct is_valid_expr; template struct expr_transform; /////////////////////////////////////////////////////////////////////////// // numeric tags /////////////////////////////////////////////////////////////////////////// template struct int_tag { }; template struct uint_tag { }; template struct real_tag { RealPolicies policies; }; /////////////////////////////////////////////////////////////////////////// // numeric specs /////////////////////////////////////////////////////////////////////////// template < typename T = int , unsigned Radix = 10 , unsigned MinDigits = 1 , int MaxDigits = -1 > struct int_spec : proto::terminal< int_tag >::type { }; template < typename T = int , unsigned Radix = 10 , unsigned MinDigits = 1 , int MaxDigits = -1 > struct uint_spec : proto::terminal< uint_tag >::type { }; /////////////////////////////////////////////////////////////////////////// template < typename T = double, typename RealPolicies = real_policies > struct real_spec : proto::terminal< real_tag >::type { private: typedef typename proto::terminal >::type base_type; base_type make_tag(RealPolicies const& p) const { base_type xpr = {{p}}; return xpr; } public: real_spec(RealPolicies const& p = RealPolicies()) : base_type(make_tag(p)) {} }; /////////////////////////////////////////////////////////////////////////// namespace detail { template struct real_policy { template static RealPolicies get(Tag) { return RealPolicies(); } template static RealPolicies const& get(real_tag const& p) { return p.policies; } }; } /////////////////////////////////////////////////////////////////////////// // get the director of an int tag /////////////////////////////////////////////////////////////////////////// template struct extract_int_director; template <> struct extract_int_director { typedef uint_parser type; }; template <> struct extract_int_director { typedef uint_parser type; }; template <> struct extract_int_director { typedef uint_parser type; }; template <> struct extract_int_director { typedef uint_parser type; }; template <> struct extract_int_director { typedef uint_parser type; }; template <> struct extract_int_director { typedef uint_parser type; }; template <> struct extract_int_director { typedef int_parser type; }; template <> struct extract_int_director { typedef int_parser type; }; template <> struct extract_int_director { typedef int_parser type; }; #ifdef BOOST_HAS_LONG_LONG template <> struct extract_int_director { typedef uint_parser type; }; template <> struct extract_int_director { typedef int_parser type; }; #endif template struct extract_int_director > { typedef int_parser type; }; template struct extract_int_director > { typedef uint_parser type; }; /////////////////////////////////////////////////////////////////////////// // get the director of a real tag /////////////////////////////////////////////////////////////////////////// template struct extract_real_director; template <> struct extract_real_director { typedef real_parser > type; }; template <> struct extract_real_director { typedef real_parser > type; }; template <> struct extract_real_director { typedef real_parser > type; }; template struct extract_real_director > { typedef real_parser type; }; /////////////////////////////////////////////////////////////////////////// // numeric parser meta-grammar /////////////////////////////////////////////////////////////////////////// struct int_meta_grammar : meta_grammar::compose_empty< proto::if_()> , qi::domain , mpl::identity > > {}; struct real_meta_grammar : meta_grammar::compose_single< proto::if_()> , qi::domain , mpl::identity > > {}; struct numeric_meta_grammar : proto::or_ { }; /////////////////////////////////////////////////////////////////////////// // These specializations non-intrusively hooks into the RD meta-grammar. // (see qi/meta_grammar.hpp) /////////////////////////////////////////////////////////////////////////// template struct is_valid_expr >::type> : mpl::true_ { }; template struct expr_transform >::type> : mpl::identity { }; }}} #endif