Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/spirit/home/karma/detail/extract_from.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
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_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM) | |
7 #define BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM | |
8 | |
9 #if defined(_MSC_VER) | |
10 #pragma once | |
11 #endif | |
12 | |
13 #include <boost/spirit/include/phoenix_core.hpp> | |
14 #include <boost/spirit/home/support/unused.hpp> | |
15 #include <boost/spirit/home/support/attributes_fwd.hpp> | |
16 #include <boost/spirit/home/karma/detail/attributes.hpp> | |
17 #include <boost/spirit/home/support/container.hpp> | |
18 | |
19 #include <boost/ref.hpp> | |
20 #include <boost/optional.hpp> | |
21 | |
22 /////////////////////////////////////////////////////////////////////////////// | |
23 namespace boost { namespace spirit { namespace traits | |
24 { | |
25 /////////////////////////////////////////////////////////////////////////// | |
26 // This file contains attribute extraction utilities. The utilities | |
27 // provided also accept spirit's unused_type; all no-ops. Compiler | |
28 // optimization will easily strip these away. | |
29 /////////////////////////////////////////////////////////////////////////// | |
30 | |
31 namespace detail | |
32 { | |
33 /////////////////////////////////////////////////////////////////////// | |
34 // extract first and second element of a fusion sequence | |
35 template <typename T> | |
36 struct add_const_ref | |
37 : add_reference<typename add_const<T>::type> | |
38 {}; | |
39 | |
40 template <typename T, int N> | |
41 struct value_at_c | |
42 : add_const_ref<typename fusion::result_of::value_at_c<T, N>::type> | |
43 {}; | |
44 } | |
45 | |
46 // This is the default case: the plain attribute values | |
47 template <typename Attribute, typename Exposed, typename Enable/*= void*/> | |
48 struct extract_from_attribute | |
49 { | |
50 typedef typename traits::one_element_sequence<Attribute>::type | |
51 is_one_element_sequence; | |
52 | |
53 typedef typename mpl::eval_if< | |
54 is_one_element_sequence | |
55 , detail::value_at_c<Attribute, 0> | |
56 , mpl::identity<Attribute const&> | |
57 >::type type; | |
58 | |
59 template <typename Context> | |
60 static type call(Attribute const& attr, Context&, mpl::false_) | |
61 { | |
62 return attr; | |
63 } | |
64 | |
65 // This handles the case where the attribute is a single element fusion | |
66 // sequence. We silently extract the only element and treat it as the | |
67 // attribute to generate output from. | |
68 template <typename Context> | |
69 static type call(Attribute const& attr, Context& ctx, mpl::true_) | |
70 { | |
71 return extract_from<Exposed>(fusion::at_c<0>(attr), ctx); | |
72 } | |
73 | |
74 template <typename Context> | |
75 static type call(Attribute const& attr, Context& ctx) | |
76 { | |
77 return call(attr, ctx, is_one_element_sequence()); | |
78 } | |
79 }; | |
80 | |
81 // This handles optional attributes. | |
82 template <typename Attribute, typename Exposed> | |
83 struct extract_from_attribute<boost::optional<Attribute>, Exposed> | |
84 { | |
85 typedef Attribute const& type; | |
86 | |
87 template <typename Context> | |
88 static type call(boost::optional<Attribute> const& attr, Context& ctx) | |
89 { | |
90 return extract_from<Exposed>(boost::get<Attribute>(attr), ctx); | |
91 } | |
92 }; | |
93 | |
94 template <typename Attribute, typename Exposed> | |
95 struct extract_from_attribute<boost::optional<Attribute const>, Exposed> | |
96 { | |
97 typedef Attribute const& type; | |
98 | |
99 template <typename Context> | |
100 static type call(boost::optional<Attribute const> const& attr, Context& ctx) | |
101 { | |
102 return extract_from<Exposed>(boost::get<Attribute const>(attr), ctx); | |
103 } | |
104 }; | |
105 | |
106 // This handles attributes wrapped inside a boost::ref(). | |
107 template <typename Attribute, typename Exposed> | |
108 struct extract_from_attribute<reference_wrapper<Attribute>, Exposed> | |
109 { | |
110 typedef Attribute const& type; | |
111 | |
112 template <typename Context> | |
113 static type call(reference_wrapper<Attribute> const& attr, Context& ctx) | |
114 { | |
115 return extract_from<Exposed>(attr.get(), ctx); | |
116 } | |
117 }; | |
118 | |
119 /////////////////////////////////////////////////////////////////////////// | |
120 template <typename Attribute, typename Exposed, typename Enable> | |
121 struct extract_from_container | |
122 { | |
123 typedef typename traits::container_value<Attribute const>::type | |
124 value_type; | |
125 typedef typename is_convertible<value_type, Exposed>::type | |
126 is_convertible_to_value_type; | |
127 | |
128 typedef typename mpl::if_< | |
129 mpl::or_< | |
130 is_same<value_type, Exposed>, is_same<Attribute, Exposed> > | |
131 , Exposed const&, Exposed | |
132 >::type type; | |
133 | |
134 // handle case where container value type is convertible to result type | |
135 // we simply return the front element of the container | |
136 template <typename Context, typename Pred> | |
137 static type call(Attribute const& attr, Context&, mpl::true_, Pred) | |
138 { | |
139 // return first element from container | |
140 typedef typename traits::container_iterator<Attribute const>::type | |
141 iterator_type; | |
142 | |
143 iterator_type it = traits::begin(attr); | |
144 type result = *it; | |
145 ++it; | |
146 return result; | |
147 } | |
148 | |
149 // handle strings | |
150 template <typename Iterator> | |
151 static void append_to_string(Exposed& result, Iterator begin, Iterator end) | |
152 { | |
153 for (Iterator i = begin; i != end; ++i) | |
154 push_back(result, *i); | |
155 } | |
156 | |
157 template <typename Context> | |
158 static type call(Attribute const& attr, Context&, mpl::false_, mpl::true_) | |
159 { | |
160 typedef typename char_type_of<Attribute>::type char_type; | |
161 | |
162 Exposed result; | |
163 append_to_string(result, traits::get_begin<char_type>(attr) | |
164 , traits::get_end<char_type>(attr)); | |
165 return result; | |
166 } | |
167 | |
168 // everything else gets just passed through | |
169 template <typename Context> | |
170 static type call(Attribute const& attr, Context&, mpl::false_, mpl::false_) | |
171 { | |
172 return type(attr); | |
173 } | |
174 | |
175 template <typename Context> | |
176 static type call(Attribute const& attr, Context& ctx) | |
177 { | |
178 typedef typename mpl::and_< | |
179 traits::is_string<Exposed>, traits::is_string<Attribute> | |
180 >::type handle_strings; | |
181 | |
182 // return first element from container | |
183 return call(attr, ctx, is_convertible_to_value_type() | |
184 , handle_strings()); | |
185 } | |
186 }; | |
187 | |
188 template <typename Attribute> | |
189 struct extract_from_container<Attribute, Attribute> | |
190 { | |
191 typedef Attribute const& type; | |
192 | |
193 template <typename Context> | |
194 static type call(Attribute const& attr, Context&) | |
195 { | |
196 return attr; | |
197 } | |
198 }; | |
199 | |
200 /////////////////////////////////////////////////////////////////////////// | |
201 namespace detail | |
202 { | |
203 // overload for non-container attributes | |
204 template <typename Exposed, typename Attribute, typename Context> | |
205 inline typename spirit::result_of::extract_from<Exposed, Attribute>::type | |
206 extract_from(Attribute const& attr, Context& ctx, mpl::false_) | |
207 { | |
208 return extract_from_attribute<Attribute, Exposed>::call(attr, ctx); | |
209 } | |
210 | |
211 // overload for containers (but not for variants or optionals | |
212 // holding containers) | |
213 template <typename Exposed, typename Attribute, typename Context> | |
214 inline typename spirit::result_of::extract_from<Exposed, Attribute>::type | |
215 extract_from(Attribute const& attr, Context& ctx, mpl::true_) | |
216 { | |
217 return extract_from_container<Attribute, Exposed>::call(attr, ctx); | |
218 } | |
219 } | |
220 | |
221 template <typename Exposed, typename Attribute, typename Context> | |
222 inline typename spirit::result_of::extract_from<Exposed, Attribute>::type | |
223 extract_from(Attribute const& attr, Context& ctx | |
224 #if (defined(__GNUC__) && (__GNUC__ < 4)) || \ | |
225 (defined(__APPLE__) && defined(__INTEL_COMPILER)) | |
226 , typename enable_if<traits::not_is_unused<Attribute> >::type* | |
227 #endif | |
228 ) | |
229 { | |
230 typedef typename mpl::and_< | |
231 traits::is_container<Attribute> | |
232 , traits::not_is_variant<Attribute> | |
233 , traits::not_is_optional<Attribute> | |
234 >::type is_not_wrapped_container; | |
235 | |
236 return detail::extract_from<Exposed>(attr, ctx | |
237 , is_not_wrapped_container()); | |
238 } | |
239 | |
240 template <typename Exposed, typename Context> | |
241 inline unused_type extract_from(unused_type, Context&) | |
242 { | |
243 return unused; | |
244 } | |
245 }}} | |
246 | |
247 /////////////////////////////////////////////////////////////////////////////// | |
248 namespace boost { namespace spirit { namespace result_of | |
249 { | |
250 template <typename Exposed, typename Attribute> | |
251 struct extract_from | |
252 : mpl::if_< | |
253 mpl::and_< | |
254 traits::is_container<Attribute> | |
255 , traits::not_is_variant<Attribute> | |
256 , traits::not_is_optional<Attribute> > | |
257 , traits::extract_from_container<Attribute, Exposed> | |
258 , traits::extract_from_attribute<Attribute, Exposed> >::type | |
259 {}; | |
260 | |
261 template <typename Exposed> | |
262 struct extract_from<Exposed, unused_type> | |
263 { | |
264 typedef unused_type type; | |
265 }; | |
266 | |
267 template <typename Exposed> | |
268 struct extract_from<Exposed, unused_type const> | |
269 { | |
270 typedef unused_type type; | |
271 }; | |
272 }}} | |
273 | |
274 #endif |