File indexing completed on 2025-12-16 10:01:37
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_PHOENIX_CORE_DETAIL_FUNCTION_EVAL_HPP
0010 #define BOOST_PHOENIX_CORE_DETAIL_FUNCTION_EVAL_HPP
0011
0012 #include <boost/phoenix/core/limits.hpp>
0013 #include <boost/phoenix/support/iterate.hpp>
0014 #include <boost/phoenix/core/call.hpp>
0015 #include <boost/phoenix/core/expression.hpp>
0016 #include <boost/phoenix/core/meta_grammar.hpp>
0017 #include <boost/utility/result_of.hpp>
0018
0019 #ifndef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EVAL
0020 # include <boost/mpl/if.hpp>
0021 # include <boost/type_traits/is_reference.hpp>
0022 #endif
0023
0024 #ifdef BOOST_PHOENIX_NO_VARIADIC_EXPRESSION
0025 # include <boost/phoenix/core/detail/cpp03/function_eval_expr.hpp>
0026 #else
0027 BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG(
0028 (boost)(phoenix)(detail)(function_eval)
0029 , (meta_grammar)(meta_grammar)
0030 , _
0031 )
0032 #endif
0033
0034 namespace boost { namespace phoenix {
0035 namespace detail
0036 {
0037 template <typename T>
0038 T& help_rvalue_deduction(T& x)
0039 {
0040 return x;
0041 }
0042
0043 template <typename T>
0044 T const& help_rvalue_deduction(T const& x)
0045 {
0046 return x;
0047 }
0048
0049 struct function_eval
0050 {
0051 template <typename Sig>
0052 struct result;
0053
0054 #ifdef BOOST_PHOENIX_NO_VARIADIC_FUNCTION_EVAL
0055 template <typename This, typename F, typename Context>
0056 struct result<This(F, Context)>
0057 {
0058 typedef typename
0059 remove_reference<
0060 typename boost::result_of<evaluator(F, Context)>::type
0061 >::type
0062 fn;
0063
0064 typedef typename boost::result_of<fn()>::type type;
0065 };
0066
0067 template <typename F, typename Context>
0068 typename result<function_eval(F const&, Context const&)>::type
0069 operator()(F const & f, Context const & ctx) const
0070 {
0071 return boost::phoenix::eval(f, ctx)();
0072 }
0073
0074 template <typename F, typename Context>
0075 typename result<function_eval(F &, Context const&)>::type
0076 operator()(F & f, Context const & ctx) const
0077 {
0078 return boost::phoenix::eval(f, ctx)();
0079 }
0080
0081 #include <boost/phoenix/core/detail/cpp03/function_eval.hpp>
0082 #else
0083 template <typename, typename, typename...> struct result_impl;
0084
0085 template <typename F, typename... A, typename Head, typename... Tail>
0086 struct result_impl<F, void(A...), Head, Tail...>
0087 : result_impl<F, void(A..., Head), Tail...>
0088 {
0089 };
0090
0091 template <typename F, typename... A, typename Context>
0092 struct result_impl<F, void(A...), Context>
0093 {
0094 typedef typename
0095 remove_reference<
0096 typename boost::result_of<evaluator(F, Context)>::type
0097 >::type
0098 fn;
0099
0100 template <typename T>
0101 struct result_of_evaluator
0102 {
0103 typedef typename boost::add_reference<
0104 typename boost::add_const<
0105 typename boost::result_of<
0106 boost::phoenix::evaluator(T, Context)
0107 >::type
0108 >::type
0109 >::type type;
0110 };
0111
0112 typedef typename
0113 boost::result_of<
0114 fn(typename result_of_evaluator<A>::type...)
0115 >::type
0116 type;
0117
0118 static type call(F f, A... a, Context ctx)
0119 {
0120 return boost::phoenix::eval(f, ctx)(help_rvalue_deduction(boost::phoenix::eval(a, ctx))...);
0121 }
0122 };
0123
0124 template <typename This, typename F, typename... A>
0125 struct result<This(F, A...)>
0126 : result_impl<F, void(), A...>
0127 {
0128 };
0129
0130 template <typename F, typename... A>
0131 typename result<
0132 function_eval(
0133 F const &
0134 , typename mpl::if_<is_reference<A>, A, A const &>::type...
0135 )
0136 >::type
0137
0138 operator()(F && f, A &&... a) const
0139 {
0140 return
0141 result<
0142 function_eval(
0143 typename mpl::if_<is_reference<F>, F, F const &>::type
0144 , typename mpl::if_<is_reference<A>, A, A const &>::type...
0145 )
0146 >::call(f, a...);
0147 }
0148 #endif
0149 };
0150
0151 }
0152
0153 template <typename Dummy>
0154 struct default_actions::when<detail::rule::function_eval, Dummy>
0155 : phoenix::call<detail::function_eval>
0156 {};
0157 }}
0158
0159 #endif