Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 /// \file eval.hpp
|
Chris@16
|
3 /// Contains the eval() expression evaluator.
|
Chris@16
|
4 //
|
Chris@16
|
5 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
6 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_PROTO_EVAL_HPP_EAN_03_29_2007
|
Chris@16
|
10 #define BOOST_PROTO_EVAL_HPP_EAN_03_29_2007
|
Chris@16
|
11
|
Chris@16
|
12 #include <boost/proto/proto_fwd.hpp> // BOOST_PROTO_CALLABLE
|
Chris@16
|
13 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
14
|
Chris@16
|
15 namespace boost { namespace proto
|
Chris@16
|
16 {
|
Chris@16
|
17
|
Chris@16
|
18 namespace result_of
|
Chris@16
|
19 {
|
Chris@16
|
20 /// \brief A metafunction for calculating the return type
|
Chris@16
|
21 /// of \c proto::eval() given a certain \c Expr and \c Context
|
Chris@16
|
22 /// types.
|
Chris@16
|
23 ///
|
Chris@16
|
24 /// \note The types \c Expr and \c Context should not be
|
Chris@16
|
25 /// reference types. They may be cv-qualified, but the
|
Chris@16
|
26 /// cv-qualification on the \c Context parameter is ignored.
|
Chris@16
|
27 template<typename Expr, typename Context>
|
Chris@16
|
28 struct eval
|
Chris@16
|
29 {
|
Chris@16
|
30 typedef typename Context::template eval<Expr>::result_type type;
|
Chris@16
|
31 };
|
Chris@16
|
32 }
|
Chris@16
|
33
|
Chris@16
|
34 namespace functional
|
Chris@16
|
35 {
|
Chris@16
|
36 /// \brief A PolymorphicFunctionObject type for
|
Chris@16
|
37 /// evaluating a given Proto expression with a given
|
Chris@16
|
38 /// context.
|
Chris@16
|
39 struct eval
|
Chris@16
|
40 {
|
Chris@16
|
41 BOOST_PROTO_CALLABLE()
|
Chris@16
|
42
|
Chris@16
|
43 template<typename Sig>
|
Chris@16
|
44 struct result;
|
Chris@16
|
45
|
Chris@16
|
46 template<typename This, typename Expr, typename Context>
|
Chris@16
|
47 struct result<This(Expr, Context)>
|
Chris@16
|
48 {
|
Chris@16
|
49 typedef
|
Chris@16
|
50 typename proto::result_of::eval<
|
Chris@16
|
51 typename remove_reference<Expr>::type
|
Chris@16
|
52 , typename remove_reference<Context>::type
|
Chris@16
|
53 >::type
|
Chris@16
|
54 type;
|
Chris@16
|
55 };
|
Chris@16
|
56
|
Chris@16
|
57 /// \brief Evaluate a given Proto expression with a given
|
Chris@16
|
58 /// context.
|
Chris@16
|
59 /// \param expr The Proto expression to evaluate
|
Chris@16
|
60 /// \param context The context in which the expression should be
|
Chris@16
|
61 /// evaluated.
|
Chris@16
|
62 /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
|
Chris@16
|
63 template<typename Expr, typename Context>
|
Chris@16
|
64 typename proto::result_of::eval<Expr, Context>::type
|
Chris@16
|
65 operator ()(Expr &e, Context &ctx) const
|
Chris@16
|
66 {
|
Chris@16
|
67 return typename Context::template eval<Expr>()(e, ctx);
|
Chris@16
|
68 }
|
Chris@16
|
69
|
Chris@16
|
70 /// \overload
|
Chris@16
|
71 ///
|
Chris@16
|
72 template<typename Expr, typename Context>
|
Chris@16
|
73 typename proto::result_of::eval<Expr, Context>::type
|
Chris@16
|
74 operator ()(Expr &e, Context const &ctx) const
|
Chris@16
|
75 {
|
Chris@16
|
76 return typename Context::template eval<Expr>()(e, ctx);
|
Chris@16
|
77 }
|
Chris@16
|
78
|
Chris@16
|
79 /// \overload
|
Chris@16
|
80 ///
|
Chris@16
|
81 template<typename Expr, typename Context>
|
Chris@16
|
82 typename proto::result_of::eval<Expr const, Context>::type
|
Chris@16
|
83 operator ()(Expr const &e, Context &ctx) const
|
Chris@16
|
84 {
|
Chris@16
|
85 return typename Context::template eval<Expr const>()(e, ctx);
|
Chris@16
|
86 }
|
Chris@16
|
87
|
Chris@16
|
88 /// \overload
|
Chris@16
|
89 ///
|
Chris@16
|
90 template<typename Expr, typename Context>
|
Chris@16
|
91 typename proto::result_of::eval<Expr const, Context>::type
|
Chris@16
|
92 operator ()(Expr const &e, Context const &ctx) const
|
Chris@16
|
93 {
|
Chris@16
|
94 return typename Context::template eval<Expr const>()(e, ctx);
|
Chris@16
|
95 }
|
Chris@16
|
96 };
|
Chris@16
|
97 }
|
Chris@16
|
98
|
Chris@16
|
99 /// \brief Evaluate a given Proto expression with a given
|
Chris@16
|
100 /// context.
|
Chris@16
|
101 /// \param expr The Proto expression to evaluate
|
Chris@16
|
102 /// \param context The context in which the expression should be
|
Chris@16
|
103 /// evaluated.
|
Chris@16
|
104 /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
|
Chris@16
|
105 template<typename Expr, typename Context>
|
Chris@16
|
106 typename proto::result_of::eval<Expr, Context>::type
|
Chris@16
|
107 eval(Expr &e, Context &ctx)
|
Chris@16
|
108 {
|
Chris@16
|
109 return typename Context::template eval<Expr>()(e, ctx);
|
Chris@16
|
110 }
|
Chris@16
|
111
|
Chris@16
|
112 /// \overload
|
Chris@16
|
113 ///
|
Chris@16
|
114 template<typename Expr, typename Context>
|
Chris@16
|
115 typename proto::result_of::eval<Expr, Context>::type
|
Chris@16
|
116 eval(Expr &e, Context const &ctx)
|
Chris@16
|
117 {
|
Chris@16
|
118 return typename Context::template eval<Expr>()(e, ctx);
|
Chris@16
|
119 }
|
Chris@16
|
120
|
Chris@16
|
121 /// \overload
|
Chris@16
|
122 ///
|
Chris@16
|
123 template<typename Expr, typename Context>
|
Chris@16
|
124 typename proto::result_of::eval<Expr const, Context>::type
|
Chris@16
|
125 eval(Expr const &e, Context &ctx)
|
Chris@16
|
126 {
|
Chris@16
|
127 return typename Context::template eval<Expr const>()(e, ctx);
|
Chris@16
|
128 }
|
Chris@16
|
129
|
Chris@16
|
130 /// \overload
|
Chris@16
|
131 ///
|
Chris@16
|
132 template<typename Expr, typename Context>
|
Chris@16
|
133 typename proto::result_of::eval<Expr const, Context>::type
|
Chris@16
|
134 eval(Expr const &e, Context const &ctx)
|
Chris@16
|
135 {
|
Chris@16
|
136 return typename Context::template eval<Expr const>()(e, ctx);
|
Chris@16
|
137 }
|
Chris@16
|
138 }}
|
Chris@16
|
139
|
Chris@16
|
140 #endif
|