| // Copyright (c) 2001-2009 Hartmut Kaiser |
| // |
| // 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_MAY_08_2007_0824AM) |
| #define BOOST_SPIRIT_META_GRAMMAR_MAY_08_2007_0824AM |
| |
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
| #pragma once // MS compatible compilers support #pragma once |
| #endif |
| |
| #include <boost/spirit/home/qi/domain.hpp> |
| #include <boost/spirit/home/support/placeholders.hpp> |
| #include <boost/spirit/home/support/meta_grammar.hpp> |
| #include <boost/spirit/home/support/detail/integer/endian.hpp> |
| #include <boost/mpl/identity.hpp> |
| #include <boost/mpl/bool.hpp> |
| #include <boost/utility/enable_if.hpp> |
| |
| namespace boost { namespace spirit { namespace qi |
| { |
| /////////////////////////////////////////////////////////////////////////// |
| // forwards |
| /////////////////////////////////////////////////////////////////////////// |
| template <integer::endianness endian, int bits> |
| struct any_binary_director; |
| |
| template <integer::endianness endian, int bits> |
| struct binary_lit_director; |
| |
| struct main_meta_grammar; |
| |
| template <typename Expr, typename Enable> |
| struct is_valid_expr; |
| |
| template <typename Expr, typename Enable> |
| struct expr_transform; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // get the director of an integer based binary literal type |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename T> |
| struct extract_literal_bin_director |
| { |
| typedef binary_lit_director< |
| boost::integer::native, sizeof(T)*CHAR_BIT |
| > type; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // get the director of a binary tag |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename Tag> |
| struct extract_binary_director; |
| |
| // native endian binaries |
| template <> |
| struct extract_binary_director<tag::byte> |
| { |
| typedef any_binary_director<boost::integer::native, 8> type; |
| }; |
| |
| template <> |
| struct extract_binary_director<tag::word> |
| { |
| typedef any_binary_director<boost::integer::native, 16> type; |
| }; |
| |
| template <> |
| struct extract_binary_director<tag::dword> |
| { |
| typedef any_binary_director<boost::integer::native, 32> type; |
| }; |
| |
| // big endian binaries |
| template <> |
| struct extract_binary_director<tag::big_word> |
| { |
| typedef any_binary_director<boost::integer::big, 16> type; |
| }; |
| |
| template <> |
| struct extract_binary_director<tag::big_dword> |
| { |
| typedef any_binary_director<boost::integer::big, 32> type; |
| }; |
| |
| // little endian binaries |
| template <> |
| struct extract_binary_director<tag::little_word> |
| { |
| typedef any_binary_director<boost::integer::little, 16> type; |
| }; |
| |
| template <> |
| struct extract_binary_director<tag::little_dword> |
| { |
| typedef any_binary_director<boost::integer::little, 32> type; |
| }; |
| |
| #ifdef BOOST_HAS_LONG_LONG |
| template <> |
| struct extract_binary_director<tag::qword> |
| { |
| typedef any_binary_director<boost::integer::native, 64> type; |
| }; |
| |
| template <> |
| struct extract_binary_director<tag::big_qword> |
| { |
| typedef any_binary_director<boost::integer::big, 64> type; |
| }; |
| |
| template <> |
| struct extract_binary_director<tag::little_qword> |
| { |
| typedef any_binary_director<boost::integer::little, 64> type; |
| }; |
| #endif |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // get the director of a binary literal tag |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename Tag, typename T> |
| struct extract_binary_lit_director; |
| |
| // native endian binaries |
| template <typename T> |
| struct extract_binary_lit_director<tag::byte, T> |
| { |
| typedef binary_lit_director<boost::integer::native, 8> type; |
| }; |
| |
| template <typename T> |
| struct extract_binary_lit_director<tag::word, T> |
| { |
| typedef binary_lit_director<boost::integer::native, 16> type; |
| }; |
| |
| template <typename T> |
| struct extract_binary_lit_director<tag::dword, T> |
| { |
| typedef binary_lit_director<boost::integer::native, 32> type; |
| }; |
| |
| // big endian binaries |
| template <typename T> |
| struct extract_binary_lit_director<tag::big_word, T> |
| { |
| typedef binary_lit_director<boost::integer::big, 16> type; |
| }; |
| |
| template <typename T> |
| struct extract_binary_lit_director<tag::big_dword, T> |
| { |
| typedef binary_lit_director<boost::integer::big, 32> type; |
| }; |
| |
| // little endian binaries |
| template <typename T> |
| struct extract_binary_lit_director<tag::little_word, T> |
| { |
| typedef binary_lit_director<boost::integer::little, 16> type; |
| }; |
| |
| template <typename T> |
| struct extract_binary_lit_director<tag::little_dword, T> |
| { |
| typedef binary_lit_director<boost::integer::little, 32> type; |
| }; |
| |
| #ifdef BOOST_HAS_LONG_LONG |
| template <typename T> |
| struct extract_binary_lit_director<tag::qword, T> |
| { |
| typedef binary_lit_director<boost::integer::native, 64> type; |
| }; |
| |
| template <typename T> |
| struct extract_binary_lit_director<tag::big_qword, T> |
| { |
| typedef binary_lit_director<boost::integer::big, 64> type; |
| }; |
| |
| template <typename T> |
| struct extract_binary_lit_director<tag::little_qword, T> |
| { |
| typedef binary_lit_director<boost::integer::little, 64> type; |
| }; |
| #endif |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // binary meta-grammar |
| /////////////////////////////////////////////////////////////////////////// |
| // literals: 10, 10L, 10LL |
| struct int_binary_meta_grammar |
| : meta_grammar::compose_empty< |
| proto::if_< |
| is_int_lit_tag<proto::_child, qi::domain>() |
| >, |
| qi::domain, |
| mpl::identity<extract_literal_bin_director<mpl::_> > |
| > |
| { |
| }; |
| |
| struct binary_meta_grammar |
| : proto::or_< |
| meta_grammar::compose_empty< |
| proto::if_< |
| is_binary_tag<proto::_child, qi::domain>() |
| >, |
| qi::domain, |
| mpl::identity<extract_binary_director<mpl::_> > |
| >, |
| meta_grammar::compose_function1_eval< |
| proto::function< |
| proto::if_< |
| is_binary_tag<proto::_child, qi::domain>() |
| >, |
| int_binary_meta_grammar |
| >, |
| qi::domain, |
| mpl::identity<extract_binary_lit_director<mpl::_, mpl::_> > |
| > |
| > |
| { |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // These specializations non-intrusively hooks into the Qi meta-grammar. |
| // (see qi/meta_grammar.hpp) |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename Expr> |
| struct is_valid_expr< |
| Expr, |
| typename enable_if< |
| proto::matches<Expr, binary_meta_grammar> |
| >::type |
| > |
| : mpl::true_ |
| { |
| }; |
| |
| template <typename Expr> |
| struct expr_transform< |
| Expr, |
| typename enable_if< |
| proto::matches<Expr, binary_meta_grammar> |
| >::type |
| > |
| : mpl::identity<binary_meta_grammar> |
| { |
| }; |
| |
| }}} |
| |
| #endif |