// Copyright (c) 2001-2010 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_SUPPORT_META_CREATE_NOV_21_2009_0327PM) #define BOOST_SPIRIT_SUPPORT_META_CREATE_NOV_21_2009_0327PM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include #include // needed for workaround below #if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3)) #include #endif namespace boost { namespace spirit { namespace traits { /////////////////////////////////////////////////////////////////////////// // This is the main dispatch point for meta_create to the correct domain template struct meta_create; /////////////////////////////////////////////////////////////////////////// // This allows to query whether a valid mapping exists for the given data // type to a component in the given domain template struct meta_create_exists : mpl::false_ {}; }}} namespace boost { namespace spirit { /////////////////////////////////////////////////////////////////////////// namespace detail { template struct add_const_ref : add_reference::type> {}; template struct remove_const_ref : remove_const::type> {}; // starting with Boost V1.42 fusion::fold has been changed to be compatible // with mpl::fold (the sequence of template parameters for the meta-function // object has been changed) #if BOOST_VERSION < 104200 /////////////////////////////////////////////////////////////////////// template struct nary_proto_expr_function { template struct result; // this is a workaround for older versions of g++ (< V4.3) which apparently have // problems with the following template specialization #if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3)) template struct result { BOOST_STATIC_ASSERT((is_same::value)); #else template struct result { #endif typedef typename remove_const_ref::type left_type; typedef typename spirit::traits::meta_create::type right_type; typedef typename mpl::eval_if< traits::not_is_unused , proto::result_of::make_expr , mpl::identity >::type type; }; template typename result::type operator()(T, unused_type const&) const { typedef spirit::traits::meta_create right_type; return right_type::call(); } template typename result::type operator()(T1, T2 const& t2) const { // we variants to the alternative operator typedef spirit::traits::meta_create right_type; return proto::make_expr(t2, right_type::call()); } }; #else /////////////////////////////////////////////////////////////////////// template struct nary_proto_expr_function { template struct result; // this is a workaround for older versions of g++ (< V4.3) which apparently have // problems with the following template specialization #if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3)) template struct result { BOOST_STATIC_ASSERT((is_same::value)); #else template struct result { #endif typedef typename remove_const_ref::type left_type; typedef typename spirit::traits::meta_create::type right_type; typedef typename mpl::eval_if< traits::not_is_unused , proto::result_of::make_expr , mpl::identity >::type type; }; template typename result::type operator()(unused_type const&, T) const { typedef spirit::traits::meta_create right_type; return right_type::call(); } template typename result::type operator()(T1 const& t1, T2) const { // we variants to the alternative operator typedef spirit::traits::meta_create right_type; return proto::make_expr(t1, right_type::call()); } }; #endif } /////////////////////////////////////////////////////////////////////// template struct make_unary_proto_expr { typedef spirit::traits::meta_create subject_type; typedef typename proto::result_of::make_expr< OpTag, typename subject_type::type >::type type; static type call() { return proto::make_expr(subject_type::call()); } }; /////////////////////////////////////////////////////////////////////////// template struct make_nary_proto_expr { typedef detail::nary_proto_expr_function make_proto_expr; typedef typename fusion::result_of::fold< Sequence, unused_type, make_proto_expr >::type type; static type call() { return fusion::fold(Sequence(), unused, make_proto_expr()); } }; }} #endif