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