]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (c) 2001-2011 Hartmut Kaiser |
2 | // | |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | #if !defined(BOOST_SPIRIT_ADAPT_ADT_ATTRIBUTES_SEP_15_2010_1219PM) | |
7 | #define BOOST_SPIRIT_ADAPT_ADT_ATTRIBUTES_SEP_15_2010_1219PM | |
8 | ||
9 | #if defined(_MSC_VER) | |
10 | #pragma once | |
11 | #endif | |
12 | ||
13 | #include <boost/spirit/home/support/attributes.hpp> | |
14 | #include <boost/spirit/home/support/container.hpp> | |
15 | #include <boost/spirit/home/support/numeric_traits.hpp> | |
16 | #include <boost/fusion/include/adapt_adt.hpp> | |
17 | #include <boost/utility/enable_if.hpp> | |
18 | ||
19 | /////////////////////////////////////////////////////////////////////////////// | |
20 | // customization points allowing to use adapted classes with spirit | |
21 | namespace boost { namespace spirit { namespace traits | |
22 | { | |
23 | /////////////////////////////////////////////////////////////////////////// | |
24 | template <typename T, int N, bool Const, typename Domain> | |
25 | struct not_is_variant< | |
26 | fusion::extension::adt_attribute_proxy<T, N, Const>, Domain> | |
27 | : not_is_variant< | |
28 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
29 | , Domain> | |
30 | {}; | |
31 | ||
32 | template <typename T, int N, bool Const, typename Domain> | |
33 | struct not_is_optional< | |
34 | fusion::extension::adt_attribute_proxy<T, N, Const>, Domain> | |
35 | : not_is_optional< | |
36 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
37 | , Domain> | |
38 | {}; | |
39 | ||
40 | /////////////////////////////////////////////////////////////////////////// | |
41 | template <typename T, int N, bool Const> | |
42 | struct is_container<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
43 | : is_container< | |
44 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
45 | > | |
46 | {}; | |
47 | ||
48 | template <typename T, int N, bool Const> | |
49 | struct container_value<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
50 | : container_value< | |
51 | typename remove_reference< | |
52 | typename fusion::extension::adt_attribute_proxy< | |
53 | T, N, Const | |
54 | >::type | |
55 | >::type | |
56 | > | |
57 | {}; | |
58 | ||
59 | template <typename T, int N, bool Const> | |
60 | struct container_value< | |
61 | fusion::extension::adt_attribute_proxy<T, N, Const> const> | |
62 | : container_value< | |
63 | typename add_const< | |
64 | typename remove_reference< | |
65 | typename fusion::extension::adt_attribute_proxy< | |
66 | T, N, Const | |
67 | >::type | |
68 | >::type | |
69 | >::type | |
70 | > | |
71 | {}; | |
72 | ||
73 | template <typename T, int N, typename Val> | |
74 | struct push_back_container< | |
75 | fusion::extension::adt_attribute_proxy<T, N, false> | |
76 | , Val | |
77 | , typename enable_if<is_reference< | |
78 | typename fusion::extension::adt_attribute_proxy<T, N, false>::type | |
79 | > >::type> | |
80 | { | |
81 | static bool call( | |
82 | fusion::extension::adt_attribute_proxy<T, N, false>& p | |
83 | , Val const& val) | |
84 | { | |
85 | typedef typename | |
86 | fusion::extension::adt_attribute_proxy<T, N, false>::type | |
87 | type; | |
88 | return push_back(type(p), val); | |
89 | } | |
90 | }; | |
91 | ||
92 | template <typename T, int N, bool Const> | |
93 | struct container_iterator< | |
94 | fusion::extension::adt_attribute_proxy<T, N, Const> > | |
95 | : container_iterator< | |
96 | typename remove_reference< | |
97 | typename fusion::extension::adt_attribute_proxy< | |
98 | T, N, Const | |
99 | >::type | |
100 | >::type | |
101 | > | |
102 | {}; | |
103 | ||
104 | template <typename T, int N, bool Const> | |
105 | struct container_iterator< | |
106 | fusion::extension::adt_attribute_proxy<T, N, Const> const> | |
107 | : container_iterator< | |
108 | typename add_const< | |
109 | typename remove_reference< | |
110 | typename fusion::extension::adt_attribute_proxy< | |
111 | T, N, Const | |
112 | >::type | |
113 | >::type | |
114 | >::type | |
115 | > | |
116 | {}; | |
117 | ||
118 | template <typename T, int N, bool Const> | |
119 | struct begin_container<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
120 | { | |
121 | typedef typename remove_reference< | |
122 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
123 | >::type container_type; | |
124 | ||
125 | static typename container_iterator<container_type>::type | |
126 | call(fusion::extension::adt_attribute_proxy<T, N, Const>& c) | |
127 | { | |
128 | return c.get().begin(); | |
129 | } | |
130 | }; | |
131 | ||
132 | template <typename T, int N, bool Const> | |
133 | struct begin_container<fusion::extension::adt_attribute_proxy<T, N, Const> const> | |
134 | { | |
135 | typedef typename add_const< | |
136 | typename remove_reference< | |
137 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
138 | >::type | |
139 | >::type container_type; | |
140 | ||
141 | static typename container_iterator<container_type>::type | |
142 | call(fusion::extension::adt_attribute_proxy<T, N, Const> const& c) | |
143 | { | |
144 | return c.get().begin(); | |
145 | } | |
146 | }; | |
147 | ||
148 | template <typename T, int N, bool Const> | |
149 | struct end_container<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
150 | { | |
151 | typedef typename remove_reference< | |
152 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
153 | >::type container_type; | |
154 | ||
155 | static typename container_iterator<container_type>::type | |
156 | call(fusion::extension::adt_attribute_proxy<T, N, Const>& c) | |
157 | { | |
158 | return c.get().end(); | |
159 | } | |
160 | }; | |
161 | ||
162 | template <typename T, int N, bool Const> | |
163 | struct end_container<fusion::extension::adt_attribute_proxy<T, N, Const> const> | |
164 | { | |
165 | typedef typename add_const< | |
166 | typename remove_reference< | |
167 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
168 | >::type | |
169 | >::type container_type; | |
170 | ||
171 | static typename container_iterator<container_type>::type | |
172 | call(fusion::extension::adt_attribute_proxy<T, N, Const> const& c) | |
173 | { | |
174 | return c.get().end(); | |
175 | } | |
176 | }; | |
177 | ||
178 | /////////////////////////////////////////////////////////////////////////// | |
179 | template <typename T, int N, typename Val> | |
180 | struct assign_to_attribute_from_value< | |
181 | fusion::extension::adt_attribute_proxy<T, N, false> | |
182 | , Val> | |
183 | { | |
184 | static void | |
185 | call(Val const& val | |
186 | , fusion::extension::adt_attribute_proxy<T, N, false>& attr) | |
187 | { | |
188 | attr = val; | |
189 | } | |
190 | }; | |
191 | ||
192 | template <typename T, int N, bool Const, typename Exposed> | |
193 | struct extract_from_attribute< | |
194 | fusion::extension::adt_attribute_proxy<T, N, Const>, Exposed> | |
195 | { | |
92f5a8d4 TL |
196 | typedef |
197 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
198 | get_return_type; | |
7c673cae FG |
199 | typedef typename remove_const< |
200 | typename remove_reference< | |
92f5a8d4 | 201 | get_return_type |
7c673cae FG |
202 | >::type |
203 | >::type embedded_type; | |
204 | typedef | |
205 | typename spirit::result_of::extract_from<Exposed, embedded_type>::type | |
92f5a8d4 TL |
206 | extracted_type; |
207 | ||
208 | // If adt_attribute_proxy returned a value we must pass the attribute | |
209 | // by value, otherwise we will end up with a reference to a temporary | |
210 | // that will expire out of scope of the function call. | |
211 | typedef typename mpl::if_c<is_reference<get_return_type>::value | |
212 | , extracted_type | |
213 | , typename remove_reference<extracted_type>::type | |
214 | >::type type; | |
7c673cae FG |
215 | |
216 | template <typename Context> | |
217 | static type | |
218 | call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val, Context& ctx) | |
219 | { | |
220 | return extract_from<Exposed>(val.get(), ctx); | |
221 | } | |
222 | }; | |
223 | ||
224 | /////////////////////////////////////////////////////////////////////////// | |
225 | template <typename T, int N, bool Const> | |
226 | struct attribute_type<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
227 | : fusion::extension::adt_attribute_proxy<T, N, Const> | |
228 | {}; | |
229 | ||
230 | /////////////////////////////////////////////////////////////////////////// | |
231 | template <typename T, int N, bool Const> | |
232 | struct optional_attribute< | |
233 | fusion::extension::adt_attribute_proxy<T, N, Const> > | |
234 | { | |
235 | typedef typename result_of::optional_value< | |
236 | typename remove_reference< | |
237 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
238 | >::type | |
239 | >::type type; | |
240 | ||
241 | static type | |
242 | call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) | |
243 | { | |
244 | return optional_value(val.get()); | |
245 | } | |
246 | ||
247 | static bool | |
248 | is_valid(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) | |
249 | { | |
250 | return has_optional_value(val.get()); | |
251 | } | |
252 | }; | |
253 | ||
254 | /////////////////////////////////////////////////////////////////////////// | |
255 | template <typename T, int N, typename Attribute, typename Domain> | |
256 | struct transform_attribute< | |
257 | fusion::extension::adt_attribute_proxy<T, N, false> | |
258 | , Attribute | |
259 | , Domain | |
260 | , typename disable_if<is_reference< | |
261 | typename fusion::extension::adt_attribute_proxy<T, N, false>::type | |
262 | > >::type> | |
263 | { | |
264 | typedef Attribute type; | |
265 | ||
266 | static Attribute | |
267 | pre(fusion::extension::adt_attribute_proxy<T, N, false>& val) | |
268 | { | |
269 | return val; | |
270 | } | |
271 | static void | |
272 | post( | |
273 | fusion::extension::adt_attribute_proxy<T, N, false>& val | |
274 | , Attribute const& attr) | |
275 | { | |
276 | val = attr; | |
277 | } | |
278 | static void | |
279 | fail(fusion::extension::adt_attribute_proxy<T, N, false>&) | |
280 | { | |
281 | } | |
282 | }; | |
283 | ||
284 | template < | |
285 | typename T, int N, bool Const, typename Attribute, typename Domain> | |
286 | struct transform_attribute< | |
287 | fusion::extension::adt_attribute_proxy<T, N, Const> | |
288 | , Attribute | |
289 | , Domain | |
290 | , typename enable_if<is_reference< | |
291 | typename fusion::extension::adt_attribute_proxy< | |
292 | T, N, Const | |
293 | >::type | |
294 | > >::type> | |
295 | { | |
296 | typedef Attribute& type; | |
297 | ||
298 | static Attribute& | |
299 | pre(fusion::extension::adt_attribute_proxy<T, N, Const>& val) | |
300 | { | |
301 | return val; | |
302 | } | |
303 | static void | |
304 | post( | |
305 | fusion::extension::adt_attribute_proxy<T, N, Const>& | |
306 | , Attribute const&) | |
307 | { | |
308 | } | |
309 | static void | |
310 | fail(fusion::extension::adt_attribute_proxy<T, N, Const>&) | |
311 | { | |
312 | } | |
313 | }; | |
314 | ||
315 | template <typename T, int N, bool Const> | |
316 | struct clear_value<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
317 | { | |
318 | static void call( | |
319 | fusion::extension::adt_attribute_proxy<T, N, Const>& val) | |
320 | { | |
321 | typedef typename | |
322 | fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
323 | type; | |
324 | clear(type(val)); | |
325 | } | |
326 | }; | |
327 | ||
328 | template <typename T, int N, bool Const> | |
329 | struct attribute_size<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
330 | { | |
331 | typedef typename remove_const< | |
332 | typename remove_reference< | |
333 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
334 | >::type | |
335 | >::type embedded_type; | |
336 | ||
337 | typedef typename attribute_size<embedded_type>::type type; | |
338 | ||
339 | static type | |
340 | call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) | |
341 | { | |
342 | return attribute_size<embedded_type>::call(val.get()); | |
343 | } | |
344 | }; | |
345 | ||
346 | /////////////////////////////////////////////////////////////////////////// | |
347 | // customization point specializations for numeric generators | |
348 | template <typename T, int N, bool Const> | |
349 | struct absolute_value<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
350 | { | |
351 | typedef typename | |
352 | fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
353 | type; | |
354 | ||
355 | static type | |
356 | call (fusion::extension::adt_attribute_proxy<T, N, Const> const& val) | |
357 | { | |
358 | return get_absolute_value(val.get()); | |
359 | } | |
360 | }; | |
361 | ||
362 | template <typename T, int N, bool Const> | |
363 | struct is_negative<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
364 | { | |
365 | static bool | |
366 | call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) | |
367 | { | |
368 | return test_negative(val.get()); | |
369 | } | |
370 | }; | |
371 | ||
372 | template <typename T, int N, bool Const> | |
373 | struct is_zero<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
374 | { | |
375 | static bool | |
376 | call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) | |
377 | { | |
378 | return test_zero(val.get()); | |
379 | } | |
380 | }; | |
381 | ||
382 | template <typename T, int N, bool Const> | |
383 | struct is_nan<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
384 | { | |
385 | static bool | |
386 | call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) | |
387 | { | |
388 | return test_nan(val.get()); | |
389 | } | |
390 | }; | |
391 | ||
392 | template <typename T, int N, bool Const> | |
393 | struct is_infinite<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
394 | { | |
395 | static bool | |
396 | call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val) | |
397 | { | |
398 | return test_infinite(val.get()); | |
399 | } | |
400 | }; | |
401 | }}} | |
402 | ||
403 | /////////////////////////////////////////////////////////////////////////////// | |
404 | namespace boost { namespace spirit { namespace result_of | |
405 | { | |
406 | template <typename T, int N, bool Const> | |
407 | struct optional_value<fusion::extension::adt_attribute_proxy<T, N, Const> > | |
408 | : result_of::optional_value< | |
409 | typename remove_const< | |
410 | typename remove_reference< | |
411 | typename fusion::extension::adt_attribute_proxy<T, N, Const>::type | |
412 | >::type | |
413 | >::type> | |
414 | {}; | |
415 | }}} | |
416 | ||
417 | #endif |