• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*==============================================================================
2     Copyright (c) 2005-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_SCOPE_SCOPED_ENVIRONMENT_HPP
9 #define BOOST_PHOENIX_SCOPE_SCOPED_ENVIRONMENT_HPP
10 
11 #include <boost/phoenix/core/limits.hpp>
12 #include <boost/mpl/int.hpp>
13 #include <boost/fusion/sequence/sequence_facade.hpp>
14 #include <boost/fusion/sequence/intrinsic/begin.hpp>
15 #include <boost/fusion/sequence/intrinsic/end.hpp>
16 #include <boost/fusion/sequence/intrinsic/size.hpp>
17 #include <boost/fusion/sequence/intrinsic/value_at.hpp>
18 #include <boost/fusion/sequence/intrinsic/at.hpp>
19 #include <boost/fusion/support/category_of.hpp>
20 #include <boost/fusion/include/pop_front.hpp>
21 #include <boost/utility/result_of.hpp>
22 
23 namespace boost { namespace phoenix
24 {
25     template<typename Env, typename OuterEnv, typename Locals, typename Map>
26     struct scoped_environment
27         : fusion::sequence_facade<
28             scoped_environment<Env, OuterEnv, Locals, Map>
29           , fusion::random_access_traversal_tag
30         >
31     {
32         typedef Env env_type;
33         typedef OuterEnv outer_env_type;
34         typedef Locals locals_type;
35         typedef Map map_type;
36 
scoped_environmentboost::phoenix::scoped_environment37         scoped_environment(
38             Env const & env_
39           , OuterEnv const &outer_env_
40           , Locals const &locals_
41         )
42             : env(env_)
43             , outer_env(outer_env_)
44             , locals(locals_)
45         {}
46 
scoped_environmentboost::phoenix::scoped_environment47         scoped_environment(scoped_environment const & o)
48             : env(o.env)
49             , outer_env(o.outer_env)
50             , locals(o.locals)
51         {}
52 
53         Env      const & env;
54         OuterEnv const & outer_env;
55         Locals   const & locals;
56 
57         typedef typename
58             fusion::result_of::pop_front<
59                 typename add_const<
60                     typename proto::detail::uncvref<Env>::type
61                 >::type
62             >::type
63             args_type;
64 
argsboost::phoenix::scoped_environment65         args_type args() const
66         {
67             return fusion::pop_front(env);
68         }
69 
70         #define BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(INTRINSIC)               \
71         template <typename Seq>                                                 \
72         struct INTRINSIC                                                        \
73         {                                                                       \
74             typedef                                                             \
75                 typename fusion::result_of::INTRINSIC<                          \
76                     typename mpl::eval_if_c<                                    \
77                         is_const<                                               \
78                             typename remove_reference<                          \
79                                 typename Seq::env_type                          \
80                             >::type                                             \
81                         >::value                                                \
82                       , add_const<                                              \
83                             typename proto::detail::uncvref<                    \
84                                 typename Seq::env_type                          \
85                             >::type                                             \
86                         >                                                       \
87                       , proto::detail::uncvref<                                 \
88                             typename Seq::env_type                              \
89                         >                                                       \
90                     >::type                                                     \
91                 >::type                                                         \
92                 type;                                                           \
93                                                                                 \
94             static type call(Seq & seq)                                         \
95             {                                                                   \
96                 return fusion::INTRINSIC(seq.env);                              \
97             }                                                                   \
98         }                                                                       \
99         /**/
100         BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(begin);
101         BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(end);
102         BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT(size);
103         #undef BOOST_PHOENIX_ADAPT_SCOPED_ENVIRONMENT
104 
105         template <typename Seq, typename N>
106         struct value_at
107         {
108             typedef
109                 typename fusion::result_of::value_at<
110                     typename mpl::eval_if_c<
111                         is_const<
112                             typename remove_reference<
113                                 typename Seq::env_type
114                             >::type
115                         >::value
116                       , add_const<
117                             typename proto::detail::uncvref<
118                                 typename Seq::env_type
119                             >::type
120                         >
121                       , proto::detail::uncvref<
122                             typename Seq::env_type
123                         >
124                     >::type
125                   , N
126                 >::type
127                 type;
128         };
129 
130         template <typename Seq, typename N>
131         struct at
132         {
133             typedef
134                 typename fusion::result_of::at<
135                     typename mpl::eval_if_c<
136                         is_const<
137                             typename remove_reference<
138                                 typename Seq::env_type
139                             >::type
140                         >::value
141                       , add_const<
142                             typename proto::detail::uncvref<
143                                 typename Seq::env_type
144                             >::type
145                         >
146                       , proto::detail::uncvref<
147                             typename Seq::env_type
148                         >
149                     >::type
150                   , N
151                 >::type
152                 type;
153 
callboost::phoenix::scoped_environment::at154             static type call(Seq & seq)
155             {
156                 return fusion::at<N>(seq.env);
157             }
158         };
159     };
160 
161     template <typename Env, typename Dummy = void>
162     struct is_scoped_environment : mpl::false_ {};
163 
164     template <typename Env>
165     struct is_scoped_environment<Env&> : is_scoped_environment<Env> {};
166 
167     template <typename Env, typename OuterEnv, typename Locals, typename Map>
168     struct is_scoped_environment<scoped_environment<Env, OuterEnv, Locals, Map> >
169         : mpl::true_
170     {};
171 
172     template <typename Env, typename OuterEnv, typename Locals, typename Map>
173     struct is_scoped_environment<scoped_environment<Env, OuterEnv, Locals, Map> const>
174         : mpl::true_
175     {};
176 }}
177 
178 #endif
179