📄 meta_grammar.hpp
字号:
// Copyright (c) 2001-2008 Hartmut Kaiser// 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_KARMA_META_GRAMMAR_FEB_23_2007_0505PM)#define BOOST_SPIRIT_KARMA_META_GRAMMAR_FEB_23_2007_0505PM#if defined(_MSC_VER) && (_MSC_VER >= 1020)#pragma once // MS compatible compilers support #pragma once#endif#include <boost/spirit/home/karma/domain.hpp>#include <boost/spirit/home/karma/numeric/numeric_fwd.hpp>#include <boost/spirit/home/support/placeholders.hpp>#include <boost/spirit/home/support/meta_grammar.hpp>#include <boost/utility/enable_if.hpp>#include <boost/mpl/identity.hpp>#include <boost/mpl/bool.hpp>namespace boost { namespace spirit { namespace karma{ template <typename Expr, typename Enable> struct is_valid_expr; template <typename Expr, typename Enable> struct expr_transform; /////////////////////////////////////////////////////////////////////////// // numeric tags /////////////////////////////////////////////////////////////////////////// template <typename T, unsigned Radix, bool ForceSign> struct int_tag {}; template <typename T, unsigned Radix, bool ForceSign> struct uint_tag {}; template <typename T, typename RealPolicies> struct real_tag { RealPolicies policies; }; /////////////////////////////////////////////////////////////////////////// // numeric specs /////////////////////////////////////////////////////////////////////////// template <typename T, unsigned Radix, bool ForceSign> struct int_spec : proto::terminal<int_tag<T, Radix, ForceSign> >::type {}; template <typename T, unsigned Radix, bool ForceSign> struct uint_spec : proto::terminal<uint_tag<T, Radix, ForceSign> >::type {}; /////////////////////////////////////////////////////////////////////////// template <typename T, typename RealPolicies> struct real_spec : proto::terminal<real_tag<T, RealPolicies> >::type { private: typedef typename proto::terminal<real_tag<T, RealPolicies> >::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 <typename RealPolicies> struct real_policy { template <typename Tag> static RealPolicies get(Tag) { return RealPolicies(); } template <typename T> static RealPolicies const& get(real_tag<T, RealPolicies> const& p) { return p.policies; } }; } }}} // namespace boost::spirit::karmanamespace boost { namespace spirit { /////////////////////////////////////////////////////////////////////////// // test if a tag is an int tag (the basic specializations are defined in // the file support/placeholders.hpp) /////////////////////////////////////////////////////////////////////////// template <typename T, unsigned Radix, bool ForceSign> struct is_int_tag<karma::int_tag<T, Radix, ForceSign>, karma::domain> : mpl::true_ {}; template <typename T, unsigned Radix, bool ForceSign> struct is_int_tag<karma::uint_tag<T, Radix, ForceSign>, karma::domain> : mpl::true_ {}; /////////////////////////////////////////////////////////////////////////// // test if a tag is a real tag (the basic specializations are defined in // the file support/placeholders.hpp) /////////////////////////////////////////////////////////////////////////// template <typename T, typename RealPolicies> struct is_real_tag<karma::real_tag<T, RealPolicies>, karma::domain> : mpl::true_ {};}} // namespace boost::spiritnamespace boost { namespace spirit { namespace karma{ /////////////////////////////////////////////////////////////////////////// // get the director of an int tag /////////////////////////////////////////////////////////////////////////// template <typename T, bool IsLiteral> struct extract_int_director; template <bool IsLiteral> struct extract_int_director<tag::bin, IsLiteral> { typedef uint_generator<IsLiteral, unsigned, 2, false> type; }; template <bool IsLiteral> struct extract_int_director<tag::oct, IsLiteral> { typedef uint_generator<IsLiteral, unsigned, 8, false> type; }; template <bool IsLiteral> struct extract_int_director<tag::hex, IsLiteral> { typedef uint_generator<IsLiteral, unsigned, 16, false> type; }; template <bool IsLiteral> struct extract_int_director<tag::ushort, IsLiteral> { typedef uint_generator<IsLiteral, unsigned short, 10, false> type; }; template <bool IsLiteral> struct extract_int_director<tag::ulong, IsLiteral> { typedef uint_generator<IsLiteral, unsigned long, 10, false> type; }; template <bool IsLiteral> struct extract_int_director<tag::uint, IsLiteral> { typedef uint_generator<IsLiteral, unsigned int, 10, false> type; }; template <bool IsLiteral> struct extract_int_director<tag::short_, IsLiteral> { typedef int_generator<IsLiteral, short, 10, false> type; }; template <bool IsLiteral> struct extract_int_director<tag::long_, IsLiteral> { typedef int_generator<IsLiteral, long, 10, false> type; }; template <bool IsLiteral> struct extract_int_director<tag::int_, IsLiteral> { typedef int_generator<IsLiteral, int, 10, false> type; };#ifdef BOOST_HAS_LONG_LONG template <bool IsLiteral> struct extract_int_director<tag::ulong_long, IsLiteral> { typedef uint_generator<IsLiteral, boost::ulong_long_type, 10, false> type; }; template <bool IsLiteral> struct extract_int_director<tag::long_long, IsLiteral> { typedef int_generator<IsLiteral, boost::long_long_type, 10, false> type; };#endif template <typename T, unsigned Radix, bool ForceSign, bool IsLiteral> struct extract_int_director<int_tag<T, Radix, ForceSign>, IsLiteral> { typedef int_generator<IsLiteral, T, Radix, ForceSign> type; }; template <typename T, unsigned Radix, bool ForceSign, bool IsLiteral> struct extract_int_director<uint_tag<T, Radix, ForceSign>, IsLiteral> { typedef uint_generator<IsLiteral, T, Radix, ForceSign> type; }; template <typename T, typename Unused> struct extract_int_director_lit : extract_int_director<T, true> {}; template <typename T> struct extract_int_director_plain : extract_int_director<T, false> {}; /////////////////////////////////////////////////////////////////////////// // get the director of a floating point literal type /////////////////////////////////////////////////////////////////////////// template <typename Tag> struct extract_literal_real_director; template <> struct extract_literal_real_director<float> { typedef real_generator<true, float, real_generator_policies<float> > type; }; template <> struct extract_literal_real_director<double> { typedef real_generator<true, double, real_generator_policies<double> > type; }; template <> struct extract_literal_real_director<long double> { typedef real_generator< true, long double, real_generator_policies<long double> > type; }; /////////////////////////////////////////////////////////////////////////// // get the director of a floating point tag /////////////////////////////////////////////////////////////////////////// template <typename Tag, bool IsLiteral> struct extract_real_director; template <bool IsLiteral> struct extract_real_director<tag::float_, IsLiteral> { typedef real_generator<IsLiteral, float, real_generator_policies<float> > type; }; template <bool IsLiteral> struct extract_real_director<tag::double_, IsLiteral> { typedef real_generator<IsLiteral, double, real_generator_policies<double> > type; }; template <bool IsLiteral> struct extract_real_director<tag::long_double, IsLiteral> { typedef real_generator< IsLiteral, long double, real_generator_policies<long double> > type; }; template <typename T, typename RealPolicies, bool IsLiteral> struct extract_real_director<real_tag<T, RealPolicies>, IsLiteral> { typedef real_generator<IsLiteral, T, RealPolicies> type; }; /////////////////////////////////////////////////////////////////////////// template <typename Tag, typename Unused> struct extract_real_director_lit : extract_real_director<Tag, true> {}; template <typename Tag> struct extract_real_director_plain : extract_real_director<Tag, false> {}; /////////////////////////////////////////////////////////////////////////// // get the director of an integer literal type /////////////////////////////////////////////////////////////////////////// template <typename T> struct extract_literal_int_director; template <> struct extract_literal_int_director<short> { typedef int_generator<true, short, 10, false> type; }; template <> struct extract_literal_int_director<unsigned short> { typedef uint_generator<true, unsigned short, 10, false> type; }; template <> struct extract_literal_int_director<int> { typedef int_generator<true, int, 10, false> type; }; template <> struct extract_literal_int_director<unsigned int> { typedef uint_generator<true, unsigned int, 10, false> type; }; template <> struct extract_literal_int_director<long> { typedef int_generator<true, long, 10, false> type; }; template <> struct extract_literal_int_director<unsigned long> { typedef uint_generator<true, unsigned long, 10, false> type; }; #ifdef BOOST_HAS_LONG_LONG template <> struct extract_literal_int_director<boost::ulong_long_type> { typedef int_generator<true, boost::ulong_long_type, 10, false> type; }; template <> struct extract_literal_int_director<boost::long_long_type> { typedef uint_generator<true, boost::long_long_type, 10, false> type; };#endif /////////////////////////////////////////////////////////////////////////// // numeric parser meta-grammar /////////////////////////////////////////////////////////////////////////// // literals: 10, 10L, 10LL struct int_literal_meta_grammar : meta_grammar::compose_empty< proto::if_< is_int_lit_tag<proto::_arg, karma::domain>() >, karma::domain, mpl::identity<extract_literal_int_director<mpl::_> > > {}; // all the different integer's as int_, uint, bin, oct, dec, hex, etc. // and the corresponding int_(10), uint(10), etc. struct int_meta_grammar : proto::or_< meta_grammar::compose_empty< proto::if_< is_int_tag<proto::_arg, karma::domain>() >, karma::domain, mpl::identity<extract_int_director_plain<mpl::_> > >, meta_grammar::compose_function1_eval< proto::function< proto::if_< is_int_tag<proto::_arg, karma::domain>() >, int_literal_meta_grammar >, karma::domain, mpl::identity<extract_int_director_lit<mpl::_, mpl::_> > > > {}; // floating point literals: 1.0, 1.0f, 10.1e2 etc. struct real_literal_meta_grammar : meta_grammar::compose_empty< proto::if_< is_real_lit_tag<proto::_arg, karma::domain>() >, karma::domain, mpl::identity<extract_literal_real_director<mpl::_> > > {}; struct real_meta_grammar : proto::or_< meta_grammar::compose_single< proto::if_< is_real_tag<proto::_arg, karma::domain>() >, karma::domain, mpl::identity<extract_real_director_plain<mpl::_> > >, meta_grammar::compose_function1_full< proto::function< proto::if_< is_real_tag<proto::_arg, karma::domain>() >, real_literal_meta_grammar >, karma::domain, mpl::identity<extract_real_director_lit<mpl::_, mpl::_> > > > {}; /////////////////////////////////////////////////////////////////////////// struct numeric_meta_grammar : proto::or_< int_meta_grammar, real_meta_grammar > {}; /////////////////////////////////////////////////////////////////////////// // These specializations non-intrusively hooks into the RD meta-grammar. // (see qi/meta_grammar.hpp) /////////////////////////////////////////////////////////////////////////// template <typename Expr> struct is_valid_expr<Expr , typename enable_if<proto::matches<Expr, numeric_meta_grammar> >::type> : mpl::true_ {}; template <typename Expr> struct expr_transform<Expr , typename enable_if<proto::matches<Expr, numeric_meta_grammar> >::type> : mpl::identity<numeric_meta_grammar> {}; }}}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -