diff --git a/include/boost/phoenix/core/detail/function_eval.hpp b/include/boost/phoenix/core/detail/function_eval.hpp index a964419..3c2a717 100644 --- a/include/boost/phoenix/core/detail/function_eval.hpp +++ b/include/boost/phoenix/core/detail/function_eval.hpp @@ -1,5 +1,6 @@ /*============================================================================= Copyright (c) 2001-2007 Joel de Guzman + Copyright (c) 2015 Kohei Takahashi 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) @@ -16,6 +17,13 @@ #include #include +#ifndef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EVAL +# include +# include +#endif + +// XXX: Currently, we should use preprocessed files since +// core/expression.hpp does not support c++11 variadic templates yet. #include namespace boost { namespace phoenix { @@ -26,7 +34,7 @@ namespace boost { namespace phoenix { { return x; } - + template T const& help_rvalue_deduction(T const& x) { @@ -38,6 +46,7 @@ namespace boost { namespace phoenix { template struct result; +#ifdef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EVAL template struct result { @@ -65,8 +74,70 @@ namespace boost { namespace phoenix { } #include +#else + template struct result_impl; + + template + struct result_impl + : result_impl + { + }; + + template + struct result_impl + { + typedef typename + remove_reference< + typename boost::result_of::type + >::type + fn; + + + typedef typename + boost::result_of< + fn( + typename boost::add_reference< + typename boost::add_const< + typename boost::result_of::type + >::type + >::type... + ) + >::type + type; + + static type call(F f, A... a, Context ctx) + { + return boost::phoenix::eval(f, ctx)(help_rvalue_deduction(boost::phoenix::eval(a, ctx))...); + } + }; + + template + struct result + : result_impl + { + }; + + template + typename result< + function_eval( + F const & + , typename mpl::if_, A, A const &>::type... + ) + >::type + // 'A &... a, Context const &ctx' doesn't work as intended: type deduction always fail. + operator()(F && f, A &&... a) const + { + return + result< + function_eval( + typename mpl::if_, F, F const &>::type + , typename mpl::if_, A, A const &>::type... + ) + >::call(f, a...); + } +#endif }; - + } template diff --git a/include/boost/phoenix/core/limits.hpp b/include/boost/phoenix/core/limits.hpp index 5f760f3..6de301d 100644 --- a/include/boost/phoenix/core/limits.hpp +++ b/include/boost/phoenix/core/limits.hpp @@ -38,9 +38,11 @@ # define BOOST_PHOENIX_NO_VARIADIC_ACTOR # define BOOST_PHOENIX_NO_VARIADIC_CALL # define BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EQUAL +# define BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EVAL #endif #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES # define BOOST_PHOENIX_NO_VARIADIC_ACTOR +# define BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EVAL #endif #if !defined(BOOST_PHOENIX_ARG_LIMIT)