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
18namespace 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
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
90 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
132 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