Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:01:37

0001 /*=============================================================================
0002     Copyright (c) 2001-2007 Joel de Guzman
0003     Copyright (c) 2015 Kohei Takahashi
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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             // 'A &... a, Context const &ctx' doesn't work as intended: type deduction always fail.
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