Imported Upstream version 1.49.0
[platform/upstream/boost.git] / boost / proto / detail / as_expr.hpp
1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file as_expr.hpp
3 /// Contains definition of the as_expr\<\> and as_child\<\> helper class
4 /// templates used to implement proto::domain's as_expr\<\> and as_child\<\>
5 /// member templates.
6 //
7 //  Copyright 2010 Eric Niebler. Distributed under the Boost
8 //  Software License, Version 1.0. (See accompanying file
9 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10
11 #ifndef BOOST_PROTO_DETAIL_AS_EXPR_HPP_EAN_06_09_2010
12 #define BOOST_PROTO_DETAIL_AS_EXPR_HPP_EAN_06_09_2010
13
14 #include <boost/config.hpp>
15 #include <boost/detail/workaround.hpp>
16 #include <boost/type_traits/remove_const.hpp>
17 #include <boost/proto/proto_fwd.hpp>
18 #include <boost/proto/args.hpp>
19
20 namespace boost { namespace proto { namespace detail
21 {
22
23     ////////////////////////////////////////////////////////////////////////////////////////////////
24     template<typename Generator>
25     struct base_generator
26     {
27         typedef Generator type;
28     };
29
30     template<typename Generator>
31     struct base_generator<use_basic_expr<Generator> >
32     {
33         typedef Generator type;
34     };
35
36     ////////////////////////////////////////////////////////////////////////////////////////////////
37     template<typename T, typename Generator, bool WantsBasicExpr>
38     struct as_expr;
39
40     ////////////////////////////////////////////////////////////////////////////////////////////////
41     template<typename T, typename Generator>
42     struct as_expr<T, Generator, false>
43     {
44         typedef typename term_traits<T &>::value_type value_type;
45         typedef proto::expr<proto::tag::terminal, term<value_type>, 0> expr_type;
46         typedef typename Generator::template result<Generator(expr_type)>::type result_type;
47
48         BOOST_FORCEINLINE
49         result_type operator()(T &t) const
50         {
51             return Generator()(expr_type::make(t));
52         }
53     };
54
55     ////////////////////////////////////////////////////////////////////////////////////////////////
56     template<typename T, typename Generator>
57     struct as_expr<T, Generator, true>
58     {
59         typedef typename term_traits<T &>::value_type value_type;
60         typedef proto::basic_expr<proto::tag::terminal, term<value_type>, 0> expr_type;
61         typedef typename Generator::template result<Generator(expr_type)>::type result_type;
62
63         BOOST_FORCEINLINE
64         result_type operator()(T &t) const
65         {
66             return Generator()(expr_type::make(t));
67         }
68     };
69
70     ////////////////////////////////////////////////////////////////////////////////////////////////
71     template<typename T>
72     struct as_expr<T, proto::default_generator, false>
73     {
74         typedef typename term_traits<T &>::value_type value_type;
75         typedef proto::expr<proto::tag::terminal, term<value_type>, 0> result_type;
76
77         BOOST_FORCEINLINE
78         result_type operator()(T &t) const
79         {
80             return result_type::make(t);
81         }
82     };
83
84     ////////////////////////////////////////////////////////////////////////////////////////////////
85     template<typename T>
86     struct as_expr<T, proto::default_generator, true>
87     {
88         typedef typename term_traits<T &>::value_type value_type;
89         typedef proto::basic_expr<proto::tag::terminal, term<value_type>, 0> result_type;
90
91         BOOST_FORCEINLINE
92         result_type operator()(T &t) const
93         {
94             return result_type::make(t);
95         }
96     };
97
98     ////////////////////////////////////////////////////////////////////////////////////////////////
99     template<typename T, typename Generator, bool WantsBasicExpr>
100     struct as_child;
101
102     ////////////////////////////////////////////////////////////////////////////////////////////////
103     template<typename T, typename Generator>
104     struct as_child<T, Generator, false>
105     {
106     #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
107         typedef typename term_traits<T &>::reference reference;
108     #else
109         typedef T &reference;
110     #endif
111         typedef proto::expr<proto::tag::terminal, term<reference>, 0> expr_type;
112         typedef typename Generator::template result<Generator(expr_type)>::type result_type;
113
114         BOOST_FORCEINLINE
115         result_type operator()(T &t) const
116         {
117             return Generator()(expr_type::make(t));
118         }
119     };
120
121     ////////////////////////////////////////////////////////////////////////////////////////////////
122     template<typename T, typename Generator>
123     struct as_child<T, Generator, true>
124     {
125     #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
126         typedef typename term_traits<T &>::reference reference;
127     #else
128         typedef T &reference;
129     #endif
130         typedef proto::basic_expr<proto::tag::terminal, term<reference>, 0> expr_type;
131         typedef typename Generator::template result<Generator(expr_type)>::type result_type;
132
133         BOOST_FORCEINLINE
134         result_type operator()(T &t) const
135         {
136             return Generator()(expr_type::make(t));
137         }
138     };
139
140     ////////////////////////////////////////////////////////////////////////////////////////////////
141     template<typename T>
142     struct as_child<T, proto::default_generator, false>
143     {
144     #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
145         typedef typename term_traits<T &>::reference reference;
146     #else
147         typedef T &reference;
148     #endif
149         typedef proto::expr<proto::tag::terminal, term<reference>, 0> result_type;
150
151         BOOST_FORCEINLINE
152         result_type operator()(T &t) const
153         {
154             return result_type::make(t);
155         }
156     };
157
158     ////////////////////////////////////////////////////////////////////////////////////////////////
159     template<typename T>
160     struct as_child<T, proto::default_generator, true>
161     {
162     #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
163         typedef typename term_traits<T &>::reference reference;
164     #else
165         typedef T &reference;
166     #endif
167         typedef proto::basic_expr<proto::tag::terminal, term<reference>, 0> result_type;
168
169         BOOST_FORCEINLINE
170         result_type operator()(T &t) const
171         {
172             return result_type::make(t);
173         }
174     };
175
176 }}}
177
178 #endif