]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/============================================================================== |
2 | Copyright (C) 2001-2011 Joel de Guzman | |
3 | Copyright (C) 2006 Dan Marsden | |
4 | ||
5 | Use, modification and distribution is subject to the Boost Software | |
6 | License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
7 | http://www.boost.org/LICENSE_1_0.txt) | |
8 | ===============================================================================/] | |
9 | [section Support] | |
10 | ||
11 | A couple of classes and metafunctions provide basic support for Fusion. | |
12 | ||
13 | [section is_sequence] | |
14 | ||
15 | [heading Description] | |
16 | ||
17 | Metafunction that evaluates to `mpl::true_` if a certain type `T` is a | |
18 | conforming Fusion __sequence__, `mpl::false_` otherwise. This may be | |
19 | specialized to accommodate clients which provide Fusion conforming sequences. | |
20 | ||
21 | [heading Synopsis] | |
22 | ||
23 | namespace traits | |
24 | { | |
25 | template <typename T> | |
26 | struct is_sequence | |
27 | { | |
28 | typedef __unspecified__ type; | |
29 | }; | |
30 | } | |
31 | ||
32 | [heading Parameters] | |
33 | ||
34 | [table | |
35 | [[Parameter] [Requirement] [Description]] | |
36 | [[`T`] [Any type] [The type to query.]] | |
37 | ] | |
38 | ||
39 | [heading Expression Semantics] | |
40 | ||
41 | typedef traits::is_sequence<T>::type c; | |
42 | ||
43 | [*Return type]: An __mpl_boolean_constant__. | |
44 | ||
45 | [*Semantics]: Metafunction that evaluates to `mpl::true_` if a certain type | |
46 | `T` is a conforming Fusion sequence, `mpl::false_` otherwise. | |
47 | ||
48 | [heading Header] | |
49 | ||
50 | #include <boost/fusion/support/is_sequence.hpp> | |
51 | #include <boost/fusion/include/is_sequence.hpp> | |
52 | ||
53 | [heading Example] | |
54 | ||
55 | BOOST_MPL_ASSERT_NOT(( traits::is_sequence< std::vector<int> > )); | |
56 | BOOST_MPL_ASSERT_NOT(( is_sequence< int > )); | |
57 | BOOST_MPL_ASSERT(( traits::is_sequence<__list__<> > )); | |
58 | BOOST_MPL_ASSERT(( traits::is_sequence<__list__<int> > )); | |
59 | BOOST_MPL_ASSERT(( traits::is_sequence<__vector__<> > )); | |
60 | BOOST_MPL_ASSERT(( traits::is_sequence<__vector__<int> > )); | |
61 | ||
62 | [endsect] | |
63 | ||
64 | [section is_view] | |
65 | ||
66 | [heading Description] | |
67 | ||
68 | Metafunction that evaluates to `mpl::true_` if a certain type `T` is a | |
69 | conforming Fusion __view__, `mpl::false_` otherwise. A view is a | |
70 | specialized sequence that does not actually contain data. Views hold | |
71 | sequences which may be other views. In general, views are held by other | |
72 | views by value, while non-views are held by other views by reference. `is_view` | |
73 | may be specialized to accommodate clients providing Fusion conforming views. | |
74 | ||
75 | [heading Synopsis] | |
76 | ||
77 | namespace traits | |
78 | { | |
79 | template <typename T> | |
80 | struct is_view | |
81 | { | |
82 | typedef __unspecified__ type; | |
83 | }; | |
84 | } | |
85 | ||
86 | [heading Parameters] | |
87 | ||
88 | [table | |
89 | [[Parameter] [Requirement] [Description]] | |
90 | [[`T`] [Any type] [The type to query.]] | |
91 | ] | |
92 | ||
93 | [heading Expression Semantics] | |
94 | ||
95 | typedef traits::is_view<T>::type c; | |
96 | ||
97 | [*Return type]: An __mpl_boolean_constant__. | |
98 | ||
99 | [*Semantics]: Metafunction that evaluates to `mpl::true_` if a certain type | |
100 | `T` is a conforming Fusion view, `mpl::false_` otherwise. | |
101 | ||
102 | [heading Header] | |
103 | ||
104 | #include <boost/fusion/support/is_view.hpp> | |
105 | #include <boost/fusion/include/is_view.hpp> | |
106 | ||
107 | [heading Example] | |
108 | ||
109 | BOOST_MPL_ASSERT_NOT(( traits::is_view<std::vector<int> > )); | |
110 | BOOST_MPL_ASSERT_NOT(( traits::is_view<int> )); | |
111 | ||
112 | using boost::mpl::_ | |
113 | using boost::is_pointer; | |
114 | typedef __vector__<int*, char, long*, bool, double> vector_type; | |
115 | typedef __filter_view__<vector_type, is_pointer<_> > filter_view_type; | |
116 | BOOST_MPL_ASSERT(( traits::is_view<filter_view_type> )); | |
117 | ||
118 | [endsect] | |
119 | ||
120 | [section tag_of] | |
121 | ||
122 | [heading Description] | |
123 | ||
124 | All conforming Fusion sequences and iterators have an associated tag type. The | |
125 | purpose of the tag is to enable __tag_dispatching__ from __intrinsic__ | |
126 | functions to implementations appropriate for the type. | |
127 | ||
128 | This metafunction may be specialized to accommodate clients providing Fusion | |
129 | conforming sequences. | |
130 | ||
131 | [heading Synopsis] | |
132 | ||
133 | namespace traits | |
134 | { | |
135 | template<typename Sequence> | |
136 | struct tag_of | |
137 | { | |
138 | typedef __unspecified__ type; | |
139 | }; | |
140 | } | |
141 | ||
142 | [heading Parameters] | |
143 | ||
144 | [table | |
145 | [[Parameter] [Requirement] [Description]] | |
146 | [[`T`] [Any type] [The type to query.]] | |
147 | ] | |
148 | ||
149 | [heading Expression Semantics] | |
150 | ||
151 | typedef traits::tag_of<T>::type tag; | |
152 | ||
153 | [*Return type]: Any type. | |
154 | ||
155 | [*Semantics]: Returns the tag type associated with `T`. | |
156 | ||
157 | [heading Header] | |
158 | ||
159 | #include <boost/fusion/support/tag_of.hpp> | |
160 | #include <boost/fusion/include/tag_of.hpp> | |
161 | ||
162 | [heading Example] | |
163 | ||
164 | typedef traits::tag_of<__list__<> >::type tag1; | |
165 | typedef traits::tag_of<__list__<int> >::type tag2; | |
166 | typedef traits::tag_of<__vector__<> >::type tag3; | |
167 | typedef traits::tag_of<__vector__<int> >::type tag4; | |
168 | ||
169 | BOOST_MPL_ASSERT((boost::is_same<tag1, tag2>)); | |
170 | BOOST_MPL_ASSERT((boost::is_same<tag3, tag4>)); | |
171 | ||
172 | [endsect] | |
173 | ||
174 | [section category_of] | |
175 | ||
176 | [heading Description] | |
177 | ||
178 | A metafunction that establishes the conceptual classification of a particular | |
179 | __sequence__ or __iterator__ (see __iterator_concepts__ and | |
180 | __sequence_concepts__). | |
181 | ||
182 | [heading Synopsis] | |
183 | ||
184 | namespace traits | |
185 | { | |
186 | template <typename T> | |
187 | struct category_of | |
188 | { | |
189 | typedef __unspecified__ type; | |
190 | }; | |
191 | } | |
192 | ||
193 | [heading Parameters] | |
194 | ||
195 | [table | |
196 | [[Parameter] [Requirement] [Description]] | |
197 | [[`T`] [Any type] [The type to query.]] | |
198 | ] | |
199 | ||
200 | [heading Expression Semantics] | |
201 | ||
202 | typedef traits::category_of<T>::type category; | |
203 | ||
204 | [*Return type]: | |
205 | ||
206 | The return type is derived from one of: | |
207 | ||
208 | namespace boost { namespace fusion | |
209 | { | |
210 | struct incrementable_traversal_tag {}; | |
211 | ||
212 | struct single_pass_traversal_tag | |
213 | : incrementable_traversal_tag {}; | |
214 | ||
215 | struct forward_traversal_tag | |
216 | : single_pass_traversal_tag {}; | |
217 | ||
218 | struct bidirectional_traversal_tag | |
219 | : forward_traversal_tag {}; | |
220 | ||
221 | struct random_access_traversal_tag | |
222 | : bidirectional_traversal_tag {}; | |
223 | }} | |
224 | ||
225 | And optionally from: | |
226 | ||
227 | namespace boost { namespace fusion | |
228 | { | |
229 | struct associative_tag {}; | |
230 | ||
231 | struct unbounded_tag {}; | |
232 | }} | |
233 | ||
234 | [*Semantics]: Establishes the conceptual classification of a particular | |
235 | __sequence__ or __iterator__. | |
236 | ||
237 | [heading Header] | |
238 | ||
239 | #include <boost/fusion/support/category_of.hpp> | |
240 | #include <boost/fusion/include/category_of.hpp> | |
241 | ||
242 | [heading Example] | |
243 | ||
244 | using boost::is_base_of; | |
245 | typedef traits::category_of<__list__<> >::type list_category; | |
246 | typedef traits::category_of<__vector__<> >::type vector_category; | |
247 | BOOST_MPL_ASSERT(( is_base_of<forward_traversal_tag, list_category> )); | |
248 | BOOST_MPL_ASSERT(( is_base_of<random_access_traversal_tag, vector_category> )); | |
249 | ||
250 | [endsect] | |
251 | ||
252 | [section deduce] | |
253 | ||
254 | [heading Description] | |
255 | Metafunction to apply __element_conversion__ to the full argument type. | |
256 | ||
257 | It removes references to `const`, references to array types are kept, even | |
258 | if the array is `const`. Reference wrappers are removed (see | |
259 | __note_ref_wrappers__)[footnote Since C++11, the standard reference wrappers | |
260 | are also removed.]. | |
261 | ||
262 | [heading Header] | |
263 | ||
264 | #include <boost/fusion/support/deduce.hpp> | |
265 | #include <boost/fusion/include/deduce.hpp> | |
266 | ||
267 | [heading Synopsis] | |
268 | namespace traits | |
269 | { | |
270 | template <typename T> | |
271 | struct deduce | |
272 | { | |
273 | typedef __unspecified__ type; | |
274 | }; | |
275 | } | |
276 | ||
277 | [heading Example] | |
278 | template <typename T> | |
279 | struct holder | |
280 | { | |
281 | typename traits::deduce<T const &>::type element; | |
282 | ||
283 | holder(T const & a) | |
284 | : element(a) | |
285 | { } | |
286 | }; | |
287 | ||
288 | template <typename T> | |
289 | holder<T> make_holder(T const & a) | |
290 | { | |
291 | return holder<T>(a); | |
292 | } | |
293 | ||
294 | [heading See also] | |
295 | * __deduce_sequence__ | |
296 | ||
297 | [endsect] | |
298 | ||
299 | [section deduce_sequence] | |
300 | ||
301 | [heading Description] | |
302 | Applies __element_conversion__ to each element in a __forward_sequence__. | |
303 | The resulting type is a __random_access_sequence__ that provides a converting | |
304 | constructor accepting the original type as its argument. | |
305 | ||
306 | [heading Header] | |
307 | ||
308 | #include <boost/fusion/support/deduce_sequence.hpp> | |
309 | #include <boost/fusion/include/deduce_sequence.hpp> | |
310 | ||
311 | [heading Synopsis] | |
312 | namespace traits | |
313 | { | |
314 | template <class Sequence> | |
315 | struct deduce_sequence | |
316 | { | |
317 | typedef __unspecified__ type; | |
318 | }; | |
319 | } | |
320 | ||
321 | [heading Example] | |
322 | template <class Seq> | |
323 | struct holder | |
324 | { | |
325 | typename traits::deduce_sequence<Seq>::type element; | |
326 | ||
327 | holder(Seq const & a) | |
328 | : element(a) | |
329 | { } | |
330 | }; | |
331 | ||
332 | template <typename T0, typename T1> | |
333 | holder< __vector__<T0 const &, T1 const &> > | |
334 | make_holder(T0 const & a0, T1 const & a1) | |
335 | { | |
336 | typedef __vector__<T0 const &, T1 const &> arg_vec_t; | |
337 | return holder<arg_vec_t>( arg_vec_t(a0,a1) ); | |
338 | } | |
339 | ||
340 | [heading See also] | |
341 | * __deduce__ | |
342 | ||
343 | [endsect] | |
344 | ||
345 | [section pair] | |
346 | ||
347 | [heading Description] | |
348 | ||
349 | Fusion `pair` type is a half runtime pair. A half runtime pair is similar | |
350 | to a __std_pair__, but, unlike __std_pair__, the first type does not have data. | |
351 | It is used as elements in __map__\ s, for example. | |
352 | ||
353 | [heading Synopsis] | |
354 | ||
355 | template <typename First, typename Second> | |
356 | struct pair; | |
357 | ||
358 | namespace result_of | |
359 | { | |
360 | template <typename Pair> | |
361 | struct first; | |
362 | ||
363 | template <typename Pair> | |
364 | struct second; | |
365 | ||
366 | template <typename First, typename Second> | |
367 | struct make_pair; | |
368 | } | |
369 | ||
370 | template <typename First, typename Second> | |
371 | typename result_of::make_pair<First,Second>::type | |
372 | make_pair(Second const &); | |
373 | ||
374 | [heading Template parameters] | |
375 | ||
376 | [table | |
377 | [[Parameter] [Description]] | |
378 | [[First] [The first type. This is purely a type. No data is held.]] | |
379 | [[Second] [The second type. This contains data.]] | |
380 | ] | |
381 | ||
382 | [variablelist Notation | |
383 | [[`P`] [Fusion pair type]] | |
384 | [[`p`, `p2`] [Fusion pairs]] | |
385 | [[`F`, `S`] [Arbitrary types]] | |
386 | [[`s`] [Value of type `S`]] | |
387 | [[`o`] [Output stream]] | |
388 | [[`i`] [Input stream]] | |
389 | ] | |
390 | ||
391 | [heading Expression Semantics] | |
392 | ||
393 | [table | |
394 | [[Expression] [Semantics]] | |
395 | [[`P::first_type`] [The type of the first template parameter, `F`, equivalent to | |
396 | `result_of::first<P>::type`. ]] | |
397 | [[`P::second_type`] [The type of the second template parameter, `S`, equivalent to | |
398 | `result_of::second<P>::type`. ]] | |
399 | [[`P()`] [Default construction.]] | |
400 | [[`P(s)`] [Construct a pair given value for the second type, `s`.]] | |
401 | [[`P(p2)`] [Copy constructs a pair from another pair, `p2`.]] | |
402 | [[`p.second`] [Get the data from `p1`.]] | |
403 | [[`p = p2`] [Assigns a pair, `p1`, from another pair, `p2`.]] | |
404 | [[make_pair<F>(s)] [Make a pair given the first type, `F`, and a value for | |
405 | the second type, `s`. The second type assumes the type of `s`]] | |
406 | [[`o << p`] [Output `p` to output stream, `o`.]] | |
407 | [[`i >> p`] [Input `p` from input stream, `i`.]] | |
408 | [[`p == p2`] [Tests two pairs for equality.]] | |
409 | [[`p != p2`] [Tests two pairs for inequality.]] | |
410 | ] | |
411 | ||
412 | [heading Header] | |
413 | ||
414 | #include <boost/fusion/support/pair.hpp> | |
415 | #include <boost/fusion/include/pair.hpp> | |
416 | ||
417 | [heading Example] | |
418 | ||
419 | pair<int, char> p('X'); | |
420 | std::cout << p << std::endl; | |
421 | std::cout << make_pair<int>('X') << std::endl; | |
422 | assert((p == make_pair<int>('X'))); | |
423 | ||
424 | [endsect] | |
425 | ||
426 | [endsect] | |
427 |