1 /*============================================================================== 2 Copyright (c) 2001-2010 Joel de Guzman 3 Copyright (c) 2010 Thomas Heller 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 #ifndef BOOST_PHOENIX_CORE_VALUE_HPP 9 #define BOOST_PHOENIX_CORE_VALUE_HPP 10 11 #include <boost/phoenix/core/limits.hpp> 12 #include <boost/phoenix/core/actor.hpp> 13 #include <boost/phoenix/core/as_actor.hpp> 14 #include <boost/phoenix/core/terminal.hpp> 15 #include <boost/phoenix/core/is_value.hpp> 16 #include <boost/utility/result_of.hpp> 17 18 namespace boost { namespace phoenix 19 { 20 //////////////////////////////////////////////////////////////////////////// 21 // 22 // values 23 // 24 // function for evaluating values, e.g. val(123) 25 // 26 //////////////////////////////////////////////////////////////////////////// 27 28 namespace expression 29 { 30 template <typename T> 31 struct value 32 : expression::terminal<T> 33 { 34 typedef 35 typename expression::terminal<T>::type 36 type; 37 /* 38 static const type make(T & t) 39 { 40 typename value<T>::type const e = {{t}}; 41 return e; 42 } 43 */ 44 }; 45 } 46 47 template <typename T> 48 inline 49 typename expression::value<T>::type const val(T t)50 val(T t) 51 { 52 return expression::value<T>::make(t); 53 } 54 55 // Identifies this Expr as a value. 56 // I think this is wrong. It is identifying all actors as values. 57 // Yes, it is giving false positives and needs a rethink. 58 // And this gives no positives. 59 //template <typename T> 60 //struct is_value<expression::value<T> > 61 // : mpl::true_ 62 //{}; 63 64 // Call out actor for special handling 65 // Is this correct? It applies to any actor. 66 // In which case why is it here? 67 template<typename Expr> 68 struct is_custom_terminal<actor<Expr> > 69 : mpl::true_ 70 {}; 71 72 // Special handling for actor 73 template<typename Expr> 74 struct custom_terminal<actor<Expr> > 75 { 76 template <typename Sig> 77 struct result; 78 79 template <typename This, typename Actor, typename Context> 80 struct result<This(Actor, Context)> 81 : boost::remove_const< 82 typename boost::remove_reference< 83 typename evaluator::impl<Actor, Context, proto::empty_env>::result_type 84 >::type 85 > 86 {}; 87 88 template <typename Context> 89 typename result<custom_terminal(actor<Expr> const &, Context &)>::type operator ()boost::phoenix::custom_terminal90 operator()(actor<Expr> const & expr, Context & ctx) const 91 { 92 typedef typename result<custom_terminal(actor<Expr> const &, Context &)>::type result_type; 93 result_type r = boost::phoenix::eval(expr, ctx); 94 // std::cout << "Evaluating val() = " << r << std::endl; 95 return r; 96 } 97 }; 98 99 namespace meta 100 { 101 template<typename T> 102 struct const_ref 103 : add_reference<typename add_const<T>::type> 104 {}; 105 106 template<typename T> 107 struct argument_type 108 : mpl::eval_if_c< 109 is_function<typename remove_pointer<T>::type>::value 110 , mpl::identity<T> 111 , const_ref<T> 112 > 113 { 114 typedef T type; 115 }; 116 117 template <typename T> 118 struct decay 119 { 120 typedef T type; 121 }; 122 template <typename T, int N> 123 struct decay<T[N]> : decay<T const *> {}; 124 } 125 126 template <typename T> 127 struct as_actor<T, mpl::false_> 128 { 129 typedef typename expression::value<typename meta::decay<T>::type >::type type; 130 131 static type convertboost::phoenix::as_actor132 convert(typename meta::argument_type<typename meta::decay<T>::type>::type t) 133 { 134 return expression::value<typename meta::decay<T>::type >::make(t); 135 } 136 }; 137 }} 138 139 #endif 140