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_REFERENCE_HPP
|
Chris@16
|
9 #define BOOST_PHOENIX_CORE_REFERENCE_HPP
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/phoenix/core/limits.hpp>
|
Chris@16
|
12 #include <boost/ref.hpp>
|
Chris@16
|
13 #include <boost/phoenix/core/actor.hpp>
|
Chris@16
|
14 #include <boost/phoenix/core/terminal.hpp>
|
Chris@16
|
15 #include <boost/utility/result_of.hpp>
|
Chris@16
|
16
|
Chris@16
|
17 namespace boost { namespace phoenix
|
Chris@16
|
18 {
|
Chris@16
|
19 /////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
20 //
|
Chris@16
|
21 // reference
|
Chris@16
|
22 //
|
Chris@16
|
23 // function for evaluating references, e.g. ref(123)
|
Chris@16
|
24 //
|
Chris@16
|
25 /////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
26 namespace expression
|
Chris@16
|
27 {
|
Chris@16
|
28 template <typename T>
|
Chris@16
|
29 struct reference
|
Chris@16
|
30 : expression::terminal<reference_wrapper<T> >
|
Chris@16
|
31 {
|
Chris@16
|
32 typedef
|
Chris@16
|
33 typename expression::terminal<reference_wrapper<T> >::type
|
Chris@16
|
34 type;
|
Chris@16
|
35
|
Chris@16
|
36 static const type make(T & t)
|
Chris@16
|
37 {
|
Chris@16
|
38 typename reference<T>::type const e = {{boost::ref(t)}};
|
Chris@16
|
39 return e;
|
Chris@16
|
40 }
|
Chris@16
|
41 };
|
Chris@16
|
42
|
Chris@16
|
43 template <typename T>
|
Chris@16
|
44 struct reference<T const>
|
Chris@16
|
45 : expression::terminal<reference_wrapper<T const> >
|
Chris@16
|
46 {
|
Chris@16
|
47 typedef
|
Chris@16
|
48 typename expression::terminal<reference_wrapper<T const> >::type
|
Chris@16
|
49 type;
|
Chris@16
|
50
|
Chris@16
|
51 static const type make(T const & t)
|
Chris@16
|
52 {
|
Chris@16
|
53 typename reference<T const>::type const e = {{boost::cref(t)}};
|
Chris@16
|
54 return e;
|
Chris@16
|
55 }
|
Chris@16
|
56 };
|
Chris@16
|
57 }
|
Chris@16
|
58
|
Chris@16
|
59 namespace rule
|
Chris@16
|
60 {
|
Chris@16
|
61 struct reference
|
Chris@16
|
62 : expression::reference<proto::_>
|
Chris@16
|
63 {};
|
Chris@16
|
64 }
|
Chris@16
|
65
|
Chris@16
|
66 template <typename T>
|
Chris@101
|
67 inline
|
Chris@16
|
68 typename expression::reference<T>::type const
|
Chris@101
|
69 ref(T & t)
|
Chris@16
|
70 {
|
Chris@16
|
71 return expression::reference<T>::make(t);
|
Chris@16
|
72 }
|
Chris@16
|
73
|
Chris@16
|
74 template <typename T>
|
Chris@101
|
75 inline
|
Chris@16
|
76 typename expression::reference<T const>::type const
|
Chris@101
|
77 cref(T const & t)
|
Chris@16
|
78 {
|
Chris@16
|
79 return expression::reference<T const>::make(t);
|
Chris@16
|
80 }
|
Chris@16
|
81
|
Chris@16
|
82 // Call out boost::reference_wrapper for special handling
|
Chris@16
|
83 template<typename T>
|
Chris@16
|
84 struct is_custom_terminal<boost::reference_wrapper<T> >
|
Chris@16
|
85 : mpl::true_
|
Chris@16
|
86 {};
|
Chris@16
|
87
|
Chris@16
|
88 // Special handling for boost::reference_wrapper
|
Chris@16
|
89 template<typename T>
|
Chris@16
|
90 struct custom_terminal<boost::reference_wrapper<T> >
|
Chris@16
|
91 {
|
Chris@16
|
92 typedef T &result_type;
|
Chris@16
|
93
|
Chris@16
|
94 template <typename Context>
|
Chris@16
|
95 T &operator()(boost::reference_wrapper<T> r, Context &) const
|
Chris@16
|
96 {
|
Chris@16
|
97 return r;
|
Chris@16
|
98 }
|
Chris@16
|
99 };
|
Chris@16
|
100
|
Chris@16
|
101 template<typename Expr>
|
Chris@16
|
102 struct custom_terminal<boost::reference_wrapper<actor<Expr> > >
|
Chris@16
|
103 {
|
Chris@16
|
104 template <typename Sig>
|
Chris@16
|
105 struct result;
|
Chris@16
|
106
|
Chris@16
|
107 template <typename This, typename Context>
|
Chris@16
|
108 struct result<This(boost::reference_wrapper<actor<Expr> > const &, Context)>
|
Chris@16
|
109 : boost::result_of<evaluator(actor<Expr> &, Context)>
|
Chris@16
|
110 {};
|
Chris@16
|
111
|
Chris@16
|
112 template <typename This, typename Context>
|
Chris@16
|
113 struct result<This(boost::reference_wrapper<actor<Expr> > &, Context)>
|
Chris@16
|
114 : boost::result_of<evaluator(actor<Expr> &, Context)>
|
Chris@16
|
115 {};
|
Chris@16
|
116
|
Chris@16
|
117 template <typename Context>
|
Chris@16
|
118 typename boost::result_of<evaluator(actor<Expr> &, Context const &)>::type
|
Chris@16
|
119 operator()(boost::reference_wrapper<actor<Expr> > & r, Context const & ctx) const
|
Chris@16
|
120 {
|
Chris@16
|
121 return boost::phoenix::eval(r, ctx);
|
Chris@16
|
122 }
|
Chris@16
|
123 };
|
Chris@16
|
124
|
Chris@16
|
125 template<typename Expr>
|
Chris@16
|
126 struct custom_terminal<boost::reference_wrapper<actor<Expr> const> >
|
Chris@16
|
127 {
|
Chris@16
|
128 template <typename Sig>
|
Chris@16
|
129 struct result;
|
Chris@16
|
130
|
Chris@16
|
131 template <typename This, typename Context>
|
Chris@16
|
132 struct result<This(boost::reference_wrapper<actor<Expr> const> const &, Context)>
|
Chris@16
|
133 : boost::result_of<evaluator(actor<Expr> const&, Context)>
|
Chris@16
|
134 {};
|
Chris@16
|
135
|
Chris@16
|
136 template <typename This, typename Context>
|
Chris@16
|
137 struct result<This(boost::reference_wrapper<actor<Expr> const> &, Context)>
|
Chris@16
|
138 : boost::result_of<evaluator(actor<Expr> const&, Context)>
|
Chris@16
|
139 {};
|
Chris@16
|
140
|
Chris@16
|
141 template <typename Context>
|
Chris@16
|
142 typename boost::result_of<evaluator(actor<Expr> const&, Context const &)>::type
|
Chris@16
|
143 operator()(boost::reference_wrapper<actor<Expr> const> const & r, Context & ctx) const
|
Chris@16
|
144 {
|
Chris@16
|
145 return boost::phoenix::eval(unwrap_ref(r), ctx);
|
Chris@16
|
146 }
|
Chris@16
|
147 };
|
Chris@16
|
148 }}
|
Chris@16
|
149
|
Chris@16
|
150 #endif
|