]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/phoenix/scope/detail/local_variable.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / phoenix / scope / detail / local_variable.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2007 Joel de Guzman
3 Copyright (c) 2004 Daniel Wallin
4 Copyright (c) 2011 Thomas Heller
5
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
9 #ifndef PHOENIX_SCOPE_DETAIL_LOCAL_VARIABLE_HPP
10 #define PHOENIX_SCOPE_DETAIL_LOCAL_VARIABLE_HPP
11
12 #include <boost/mpl/int.hpp>
13 #include <boost/mpl/bool.hpp>
14 #include <boost/mpl/eval_if.hpp>
15 #include <boost/mpl/identity.hpp>
16 #include <boost/fusion/include/at.hpp>
17 #include <boost/fusion/include/value_at.hpp>
18 #include <boost/preprocessor/enum.hpp>
19 #include <boost/preprocessor/repeat.hpp>
20 #include <boost/type_traits/remove_reference.hpp>
21 #include <boost/type_traits/is_reference.hpp>
22
23 #define BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM(z, n, data) \
24 typename T##n = unused<n>
25
26 #define BOOST_PHOENIX_MAP_LOCAL_DISPATCH(z, n, data) \
27 typedef char(&result##n)[n+2]; \
28 static result##n get(T##n*);
29
30 namespace boost { namespace phoenix
31 {
32 template <typename Env, typename OuterEnv, typename Locals, typename Map>
33 struct scoped_environment;
34
35 namespace detail
36 {
37 template <typename Key>
38 struct local
39 {
40 typedef Key key_type;
41 };
42
43 namespace result_of
44 {
45 template <typename Locals, typename Context>
46 struct initialize_locals;
47
48 template <typename Context>
49 struct initialize_locals<vector0<>, Context>
50 {
51 typedef vector0<> type;
52 };
53
54 #define M1(Z, N, D) \
55 typename boost::phoenix::result_of::eval< \
56 BOOST_PP_CAT(A, N) \
57 , Context \
58 >::type \
59 /**/
60
61 #define M0(Z, N, D) \
62 template <BOOST_PHOENIX_typename_A(N), typename Context> \
63 struct initialize_locals< \
64 BOOST_PP_CAT(vector, N)< \
65 BOOST_PHOENIX_A(N) \
66 > \
67 , Context \
68 > \
69 { \
70 typedef \
71 BOOST_PP_CAT(vector, N)< \
72 BOOST_PP_ENUM(N, M1, _) \
73 > \
74 type; \
75 }; \
76 /**/
77 BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, M0, _)
78 #undef M0
79 }
80
81 template <typename Context>
82 vector0<>
83 initialize_locals(vector0<> const &, Context const &)
84 {
85 vector0<> vars;
86 return vars;
87 }
88 #define M2(Z, N, D) \
89 eval(locals. BOOST_PP_CAT(a, N), ctx) \
90 /**/
91
92 #define M0(Z, N, D) \
93 template <BOOST_PHOENIX_typename_A(N), typename Context> \
94 BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, M1, _)> \
95 initialize_locals( \
96 BOOST_PP_CAT(vector, N)<BOOST_PHOENIX_A(N)> const & locals \
97 , Context const & ctx \
98 ) \
99 { \
100 BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM(N, M1, _)> vars \
101 = {BOOST_PP_ENUM(N, M2, _)}; \
102 return vars; \
103 } \
104 /**/
105 BOOST_PP_REPEAT_FROM_TO(1, BOOST_PHOENIX_LIMIT, M0, _)
106 #undef M0
107 #undef M1
108 #undef M2
109
110 template <int N>
111 struct unused;
112
113 template <
114 BOOST_PP_ENUM(
115 BOOST_PHOENIX_LOCAL_LIMIT
116 , BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM
117 , _
118 )
119 >
120 struct map_local_index_to_tuple
121 {
122 typedef char(&not_found)[1];
123 static not_found get(...);
124
125 BOOST_PP_REPEAT(BOOST_PHOENIX_LOCAL_LIMIT, BOOST_PHOENIX_MAP_LOCAL_DISPATCH, _)
126 };
127
128 template<typename T>
129 T* generate_pointer();
130
131 template <typename Map, typename Tag>
132 struct get_index
133 {
134 BOOST_STATIC_CONSTANT(int,
135 value = (
136 static_cast<int>((sizeof(Map::get(generate_pointer<Tag>()))) / sizeof(char)) - 2
137 ));
138
139 // if value == -1, Tag is not found
140 typedef mpl::int_<value> type;
141 };
142
143
144 template <typename Local, typename Env>
145 struct apply_local;
146
147 template <typename Local, typename Env>
148 struct outer_local
149 {
150 typedef typename
151 apply_local<Local, typename Env::outer_env_type>::type
152 type;
153 };
154
155 template <typename Locals, int Index>
156 struct get_local_or_void
157 {
158 typedef typename
159 mpl::eval_if_c<
160 Index < Locals::size_value
161 , fusion::result_of::at_c<Locals, Index>
162 , mpl::identity<fusion::void_>
163 >::type
164 type;
165 };
166
167 template <typename Local, typename Env, int Index>
168 struct get_local_from_index
169 {
170 typedef typename
171 mpl::eval_if_c<
172 Index == -1
173 , outer_local<Local, Env>
174 , get_local_or_void<typename Env::locals_type, Index>
175 >::type
176 type;
177 };
178
179 template <typename Local, typename Env>
180 struct get_local
181 {
182 static const int index_value = get_index<typename Env::map_type, Local>::value;
183
184 typedef typename
185 get_local_from_index<Local, Env, index_value>::type
186 type;
187 };
188
189 template <typename Local, typename Env>
190 struct apply_local
191 {
192 // $$$ TODO: static assert that Env is a scoped_environment $$$
193 typedef typename get_local<Local, Env>::type type;
194 };
195
196 template <typename Key>
197 struct eval_local
198 {
199 template <typename RT, int Index, typename Env>
200 static RT
201 get(Env const& env, mpl::false_)
202 {
203 return RT(fusion::at_c<Index>(env.locals));
204 }
205
206 template <typename RT, int Index, typename Env>
207 static RT
208 get(Env const& env, mpl::true_)
209 {
210 static const int index_value = get_index<typename Env::outer_env_type::map_type, detail::local<Key> >::value;
211
212 return get<RT, index_value>(
213 env.outer_env
214 , mpl::bool_<index_value == -1>());
215 }
216
217 template <typename RT, int Index, typename Env>
218 static RT
219 get(Env const& env)
220 {
221 return get<RT, Index>(
222 env
223 , mpl::bool_<Index == -1>());
224 }
225 };
226 }
227 }}
228
229 #undef BOOST_PHOENIX_MAP_LOCAL_TEMPLATE_PARAM
230 #undef BOOST_PHOENIX_MAP_LOCAL_DISPATCH
231
232 #endif