Chris@16: // Copyright (c) 2001-2011 Hartmut Kaiser Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #if !defined(BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM) Chris@16: #define BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { namespace spirit { namespace qi Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // compatible STL containers Chris@16: template Chris@16: struct meta_create_container Chris@16: { Chris@16: typedef make_unary_proto_expr< Chris@16: typename Container::value_type Chris@16: , proto::tag::dereference, qi::domain Chris@16: > make_proto_expr; Chris@16: Chris@16: typedef typename make_proto_expr::type type; Chris@16: Chris@16: static type call() Chris@16: { Chris@16: return make_proto_expr::call(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Fusion sequences Chris@16: template Chris@16: struct meta_create_sequence Chris@16: { Chris@16: // create a mpl sequence from the given fusion sequence Chris@16: typedef typename mpl::fold< Chris@16: typename fusion::result_of::as_vector::type Chris@16: , mpl::vector<>, mpl::push_back Chris@16: >::type sequence_type; Chris@16: Chris@16: typedef make_nary_proto_expr< Chris@16: sequence_type, proto::tag::shift_right, qi::domain Chris@16: > make_proto_expr; Chris@16: Chris@16: typedef typename make_proto_expr::type type; Chris@16: Chris@16: static type call() Chris@16: { Chris@16: return make_proto_expr::call(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // the default is to use the standard streaming operator unless it's a Chris@16: // STL container or a fusion sequence Chris@16: Chris@16: // The default implementation will be chosen if no predefined mapping of Chris@16: // the data type T to a Qi component is defined. Chris@16: struct no_auto_mapping_exists {}; Chris@16: Chris@16: template Chris@16: struct meta_create_impl : mpl::identity {}; Chris@16: Chris@16: template Chris@16: struct meta_create_impl, mpl::not_ > > Chris@16: >::type> Chris@16: : meta_create_container {}; Chris@16: Chris@16: template Chris@16: struct meta_create_impl Chris@16: >::type> Chris@16: : meta_create_sequence {}; Chris@16: Chris@16: template Chris@16: struct meta_create : meta_create_impl {}; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // optional Chris@16: template Chris@16: struct meta_create > Chris@16: { Chris@16: typedef make_unary_proto_expr< Chris@16: T, proto::tag::negate, qi::domain Chris@16: > make_proto_expr; Chris@16: Chris@16: typedef typename make_proto_expr::type type; Chris@16: Chris@16: static type call() Chris@16: { Chris@16: return make_proto_expr::call(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // alternatives Chris@16: template Chris@16: struct meta_create > Chris@16: { Chris@16: typedef make_nary_proto_expr< Chris@16: typename boost::variant::types Chris@16: , proto::tag::bitwise_or, qi::domain Chris@16: > make_proto_expr; Chris@16: Chris@16: typedef typename make_proto_expr::type type; Chris@16: Chris@16: static type call() Chris@16: { Chris@16: return make_proto_expr::call(); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // predefined specializations for primitive components Chris@16: Chris@16: // character generator Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::standard::char_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::standard::char_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::standard_wide::char_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::standard::char_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: Chris@16: // boolean generator Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::bool_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: Chris@16: // integral generators Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::int_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::short_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::long_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::uint_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::ushort_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: #endif Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::ulong_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: Chris@16: #ifdef BOOST_HAS_LONG_LONG Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::long_long_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::ulong_long_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: #endif Chris@16: Chris@16: // floating point generators Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::float_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::double_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: template <> Chris@16: struct meta_create Chris@16: { Chris@16: typedef spirit::long_double_type type; Chris@16: static type call() { return type(); } Chris@16: }; Chris@16: }}} Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { namespace spirit { namespace traits Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // main customization point for create_parser Chris@16: template Chris@16: struct create_parser : qi::meta_create {}; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // dispatch this to the Qi related specializations Chris@16: template Chris@16: struct meta_create Chris@16: : create_parser::type> {}; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Check whether a valid mapping exits for the given data type to a Qi Chris@16: // component Chris@16: template Chris@16: struct meta_create_exists Chris@16: : mpl::not_::type Chris@16: > > {}; Chris@16: }}} Chris@16: Chris@16: #endif