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