]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.TypeErasure library |
2 | // | |
3 | // Copyright 2011-2012 Steven Watanabe | |
4 | // | |
5 | // Distributed under the Boost Software License Version 1.0. (See | |
6 | // accompanying file LICENSE_1_0.txt or copy at | |
7 | // http://www.boost.org/LICENSE_1_0.txt) | |
8 | // | |
9 | // $Id$ | |
10 | ||
11 | #if !defined(BOOST_PP_IS_ITERATING) | |
12 | ||
13 | #ifndef BOOST_TYPE_ERASURE_TUPLE_HPP_INCLUDED | |
14 | #define BOOST_TYPE_ERASURE_TUPLE_HPP_INCLUDED | |
15 | ||
16 | #include <boost/config.hpp> | |
17 | ||
18 | ||
19 | #ifdef BOOST_TYPE_ERASURE_DOXYGEN | |
20 | ||
21 | namespace boost { | |
22 | namespace type_erasure { | |
23 | ||
24 | /** | |
25 | * @ref tuple is a Boost.Fusion Random Access Sequence containing | |
26 | * @ref any "anys". @c Concept specifies the \Concept for each | |
27 | * of the elements. The remaining arguments must be (possibly const | |
28 | * and/or reference qualified) placeholders, which are the | |
29 | * @ref placeholder "placeholders" of the elements. | |
30 | */ | |
31 | template<class Concept, class... T> | |
32 | class tuple | |
33 | { | |
34 | public: | |
35 | /** | |
36 | * Constructs a tuple. Each element of @c args will | |
37 | * be used to initialize the corresponding @ref any member. | |
38 | * The @ref binding for the tuple elements is determined | |
39 | * by mapping the placeholders in @c T to the corresponding | |
40 | * types in @c U. | |
41 | */ | |
42 | template<class... U> | |
43 | explicit tuple(U&&... args); | |
44 | }; | |
45 | ||
46 | /** | |
47 | * Returns the Nth @ref any in the tuple. | |
48 | */ | |
49 | template<int N, class Concept, class... T> | |
50 | any<Concept, TN>& get(tuple<Concept, T...>& arg); | |
51 | /** \overload */ | |
52 | template<int N, class Concept, class... T> | |
53 | const any<Concept, TN>& get(const tuple<Concept, T...>& arg); | |
54 | ||
55 | } | |
56 | } | |
57 | ||
58 | #elif !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
59 | ||
60 | #include <boost/mpl/int.hpp> | |
61 | #include <boost/mpl/bool.hpp> | |
62 | #include <boost/mpl/map.hpp> | |
63 | #include <boost/mpl/insert.hpp> | |
64 | #include <boost/type_traits/remove_reference.hpp> | |
65 | #include <boost/type_traits/remove_const.hpp> | |
66 | #include <boost/fusion/include/category_of.hpp> | |
67 | #include <boost/fusion/include/iterator_facade.hpp> | |
68 | #include <boost/fusion/include/sequence_facade.hpp> | |
69 | #include <boost/type_erasure/any.hpp> | |
70 | #include <boost/type_erasure/static_binding.hpp> | |
71 | #include <boost/type_erasure/config.hpp> | |
72 | ||
73 | namespace boost { | |
74 | namespace type_erasure { | |
75 | ||
76 | template<class Concept, class... T> | |
77 | struct cons; | |
78 | ||
79 | template<class Concept> | |
80 | struct cons<Concept> | |
81 | { | |
82 | template<class Binding> | |
83 | cons(const Binding&) {} | |
84 | }; | |
85 | ||
86 | template<class Concept, class T0, class... T> | |
87 | struct cons<Concept, T0, T...> | |
88 | { | |
89 | typedef any<Concept, T0> value_type; | |
90 | typedef cons<Concept, T...> rest_type; | |
91 | template<class Binding, class U0, class... U> | |
92 | cons(const Binding& b, U0&& u0, U&&... u) | |
93 | : value(std::forward<U0>(u0), b), | |
94 | rest(b, std::forward<U>(u)...) | |
95 | {} | |
96 | any<Concept, T0> value; | |
97 | cons<Concept, T...> rest; | |
98 | }; | |
99 | ||
100 | namespace detail { | |
101 | ||
102 | template<int N, class Cons> | |
103 | struct cons_advance | |
104 | { | |
105 | typedef typename cons_advance<N-1, Cons>::type::rest_type type; | |
106 | static const type& call(const Cons& c) | |
107 | { | |
108 | return cons_advance<N-1, Cons>::call(c).rest; | |
109 | } | |
110 | }; | |
111 | ||
112 | template<class Cons> | |
113 | struct cons_advance<0, Cons> | |
114 | { | |
115 | typedef Cons type; | |
116 | static const type& call(const Cons& c) | |
117 | { | |
118 | return c; | |
119 | } | |
120 | }; | |
121 | ||
122 | template<class... T> | |
123 | struct make_map; | |
124 | ||
125 | template<class T0, class... T> | |
126 | struct make_map<T0, T...> | |
127 | { | |
128 | typedef typename ::boost::mpl::insert< | |
129 | typename ::boost::type_erasure::detail::make_map<T...>::type, | |
130 | T0 | |
131 | >::type type; | |
132 | }; | |
133 | ||
134 | template<> | |
135 | struct make_map<> | |
136 | { | |
137 | typedef ::boost::mpl::map0<> type; | |
138 | }; | |
139 | ||
140 | } | |
141 | ||
142 | /** INTERNAL ONLY */ | |
143 | template<class Tuple, int N> | |
144 | class tuple_iterator : | |
145 | public ::boost::fusion::iterator_facade< | |
146 | tuple_iterator<Tuple, N>, | |
147 | ::boost::fusion::random_access_traversal_tag | |
148 | > | |
149 | { | |
150 | public: | |
151 | typedef ::boost::mpl::int_<N> index; | |
152 | explicit tuple_iterator(Tuple& t_arg) : t(&t_arg) {} | |
153 | template<class It> | |
154 | struct value_of | |
155 | { | |
156 | typedef typename Tuple::template value_at<Tuple, mpl::int_<N> >::type type; | |
157 | }; | |
158 | template<class It> | |
159 | struct deref | |
160 | { | |
161 | typedef typename Tuple::template at<Tuple, mpl::int_<N> >::type type; | |
162 | static type call(It it) | |
163 | { | |
164 | return Tuple::template at<Tuple, mpl::int_<N> >::call(*it.t); | |
165 | } | |
166 | }; | |
167 | template<class It, class M> | |
168 | struct advance | |
169 | { | |
170 | typedef tuple_iterator<Tuple, (It::index::value+M::value)> type; | |
171 | static type call(It it) { return type(*it.t); } | |
172 | }; | |
173 | template<class It> | |
174 | struct next : advance<It, ::boost::mpl::int_<1> > {}; | |
175 | template<class It> | |
176 | struct prior : advance<It, ::boost::mpl::int_<-1> > {}; | |
177 | template<class It1, class It2> | |
178 | struct distance | |
179 | { | |
180 | typedef typename ::boost::mpl::minus< | |
181 | typename It2::index, | |
182 | typename It1::index | |
183 | >::type type; | |
184 | static type call(It1, It2) { return type(); } | |
185 | }; | |
186 | private: | |
187 | Tuple* t; | |
188 | }; | |
189 | ||
190 | template<class Concept, class... T> | |
191 | class tuple : | |
192 | public ::boost::fusion::sequence_facade< | |
193 | ::boost::type_erasure::tuple<Concept, T...>, | |
194 | ::boost::fusion::forward_traversal_tag | |
195 | > | |
196 | { | |
197 | public: | |
198 | template<class... U> | |
199 | explicit tuple(U&&... args) | |
200 | : impl( | |
201 | ::boost::type_erasure::make_binding< | |
202 | typename ::boost::type_erasure::detail::make_map< | |
203 | ::boost::mpl::pair< | |
204 | typename ::boost::remove_const< | |
205 | typename ::boost::remove_reference<T>::type | |
206 | >::type, | |
207 | typename ::boost::remove_const< | |
208 | typename ::boost::remove_reference<U>::type | |
209 | >::type | |
210 | >... | |
211 | >::type | |
212 | >(), | |
213 | std::forward<U>(args)...) | |
214 | {} | |
215 | ||
216 | template<class Seq> | |
217 | struct begin | |
218 | { | |
219 | typedef ::boost::type_erasure::tuple_iterator< | |
220 | Seq, | |
221 | 0 | |
222 | > type; | |
223 | static type call(Seq& seq) { return type(seq); } | |
224 | }; | |
225 | template<class Seq> | |
226 | struct end | |
227 | { | |
228 | typedef ::boost::type_erasure::tuple_iterator< | |
229 | Seq, | |
230 | sizeof...(T) | |
231 | > type; | |
232 | static type call(Seq& seq) { return type(seq); } | |
233 | }; | |
234 | template<class Seq> | |
235 | struct size | |
236 | { | |
237 | typedef ::boost::mpl::int_<sizeof...(T)> type; | |
238 | static type call(Seq& seq) { return type(); } | |
239 | }; | |
240 | template<class Seq> | |
241 | struct empty | |
242 | { | |
243 | typedef ::boost::mpl::bool_<sizeof...(T) == 0> type; | |
244 | static type call(Seq& seq) { return type(); } | |
245 | }; | |
246 | template<class Seq, class N> | |
247 | struct at | |
248 | { | |
249 | typedef typename ::boost::type_erasure::detail::cons_advance< | |
250 | N::value, | |
251 | ::boost::type_erasure::cons<Concept, T...> | |
252 | >::type::value_type value_type; | |
253 | typedef typename ::boost::mpl::if_< ::boost::is_const<Seq>, | |
254 | const value_type&, | |
255 | value_type& | |
256 | >::type type; | |
257 | static type call(Seq& seq) | |
258 | { | |
259 | return const_cast<type>( | |
260 | ::boost::type_erasure::detail::cons_advance< | |
261 | N::value, | |
262 | ::boost::type_erasure::cons<Concept, T...> | |
263 | >::call(seq.impl).value | |
264 | ); | |
265 | } | |
266 | }; | |
267 | template<class Seq, class N> | |
268 | struct value_at | |
269 | { | |
270 | typedef typename ::boost::type_erasure::detail::cons_advance< | |
271 | N::value, | |
272 | ::boost::type_erasure::cons<Concept, T...> | |
273 | >::type::value_type value_type; | |
274 | }; | |
275 | ::boost::type_erasure::cons<Concept, T...> impl; | |
276 | }; | |
277 | ||
278 | template<int N, class Concept, class... T> | |
279 | typename ::boost::type_erasure::detail::cons_advance< | |
280 | N, | |
281 | ::boost::type_erasure::cons<Concept, T...> | |
282 | >::type::value_type& get(::boost::type_erasure::tuple<Concept, T...>& t) | |
283 | { | |
284 | return const_cast< | |
285 | typename ::boost::type_erasure::detail::cons_advance< | |
286 | N, | |
287 | ::boost::type_erasure::cons<Concept, T...> | |
288 | >::type::value_type& | |
289 | >( | |
290 | ::boost::type_erasure::detail::cons_advance<N, | |
291 | ::boost::type_erasure::cons<Concept, T...> | |
292 | >::call(t.impl).value | |
293 | ); | |
294 | } | |
295 | ||
296 | template<int N, class Concept, class... T> | |
297 | const typename ::boost::type_erasure::detail::cons_advance< | |
298 | N, | |
299 | ::boost::type_erasure::cons<Concept, T...> | |
300 | >::type::value_type& get(const ::boost::type_erasure::tuple<Concept, T...>& t) | |
301 | { | |
302 | return ::boost::type_erasure::detail::cons_advance< | |
303 | N, | |
304 | ::boost::type_erasure::cons<Concept, T...> | |
305 | >::call(t.impl).value; | |
306 | } | |
307 | ||
308 | } | |
309 | } | |
310 | ||
311 | #else | |
312 | ||
313 | #include <boost/mpl/int.hpp> | |
314 | #include <boost/mpl/minus.hpp> | |
315 | #include <boost/mpl/equal_to.hpp> | |
316 | #include <boost/mpl/map.hpp> | |
317 | #include <boost/fusion/include/category_of.hpp> | |
318 | #include <boost/fusion/include/iterator_facade.hpp> | |
319 | #include <boost/fusion/include/sequence_facade.hpp> | |
320 | #include <boost/preprocessor/cat.hpp> | |
321 | #include <boost/preprocessor/iteration/iterate.hpp> | |
322 | #include <boost/preprocessor/repetition/repeat.hpp> | |
323 | #include <boost/preprocessor/repetition/enum.hpp> | |
324 | #include <boost/preprocessor/repetition/enum_params.hpp> | |
325 | #include <boost/preprocessor/repetition/enum_trailing_params.hpp> | |
326 | #include <boost/preprocessor/repetition/enum_binary_params.hpp> | |
327 | #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp> | |
328 | #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp> | |
329 | #include <boost/type_erasure/any.hpp> | |
330 | #include <boost/type_erasure/static_binding.hpp> | |
331 | #include <boost/type_erasure/config.hpp> | |
332 | ||
333 | namespace boost { | |
334 | namespace type_erasure { | |
335 | ||
336 | /** INTERNAL ONLY */ | |
337 | struct na {}; | |
338 | ||
339 | namespace detail { | |
340 | ||
341 | template<int N, class Tuple> | |
342 | struct get_impl; | |
343 | ||
344 | template<class Concept, | |
345 | BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( | |
346 | BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, class T, ::boost::type_erasure::na)> | |
347 | struct tuple_storage; | |
348 | ||
349 | } | |
350 | ||
351 | /** INTERNAL ONLY */ | |
352 | template<class Tuple, int N> | |
353 | class tuple_iterator : | |
354 | public ::boost::fusion::iterator_facade< | |
355 | tuple_iterator<Tuple, N>, | |
356 | ::boost::fusion::random_access_traversal_tag | |
357 | > | |
358 | { | |
359 | public: | |
360 | typedef ::boost::mpl::int_<N> index; | |
361 | explicit tuple_iterator(Tuple& t_arg) : t(&t_arg) {} | |
362 | template<class It> | |
363 | struct value_of | |
364 | { | |
365 | typedef typename ::boost::type_erasure::detail::get_impl< | |
366 | It::index::value, | |
367 | Tuple | |
368 | >::value_type type; | |
369 | }; | |
370 | template<class It> | |
371 | struct deref : | |
372 | ::boost::type_erasure::detail::get_impl<It::index::value, Tuple> | |
373 | { | |
374 | typedef typename ::boost::type_erasure::detail::get_impl< | |
375 | It::index::value, | |
376 | Tuple | |
377 | >::type type; | |
378 | static type call(It it) | |
379 | { | |
380 | return ::boost::type_erasure::detail::get_impl< | |
381 | It::index::value, | |
382 | Tuple | |
383 | >::call(*it.t); | |
384 | } | |
385 | }; | |
386 | template<class It, class M> | |
387 | struct advance | |
388 | { | |
389 | typedef tuple_iterator<Tuple, (It::index::value+M::value)> type; | |
390 | static type call(It it) { return type(*it.t); } | |
391 | }; | |
392 | template<class It> | |
393 | struct next : advance<It, ::boost::mpl::int_<1> > {}; | |
394 | template<class It> | |
395 | struct prior : advance<It, ::boost::mpl::int_<-1> > {}; | |
396 | template<class It1, class It2> | |
397 | struct distance | |
398 | { | |
399 | typedef typename ::boost::mpl::minus< | |
400 | typename It2::index, | |
401 | typename It1::index | |
402 | >::type type; | |
403 | static type call(It1, It2) { return type(); } | |
404 | }; | |
405 | private: | |
406 | Tuple* t; | |
407 | }; | |
408 | ||
409 | /** INTERNAL ONLY */ | |
410 | template<class Derived> | |
411 | struct tuple_base : | |
412 | ::boost::fusion::sequence_facade< | |
413 | Derived, | |
414 | ::boost::fusion::random_access_traversal_tag | |
415 | > | |
416 | { | |
417 | template<class Seq> | |
418 | struct begin | |
419 | { | |
420 | typedef ::boost::type_erasure::tuple_iterator<Seq, 0> type; | |
421 | static type call(Seq& seq) { return type(seq); } | |
422 | }; | |
423 | template<class Seq> | |
424 | struct end | |
425 | { | |
426 | typedef ::boost::type_erasure::tuple_iterator< | |
427 | Seq, | |
428 | Seq::tuple_size::value | |
429 | > type; | |
430 | static type call(Seq& seq) { return type(seq); } | |
431 | }; | |
432 | template<class Seq> | |
433 | struct size | |
434 | { | |
435 | typedef typename Seq::tuple_size type; | |
436 | static type call(Seq& seq) { return type(); } | |
437 | }; | |
438 | template<class Seq> | |
439 | struct empty | |
440 | { | |
441 | typedef typename boost::mpl::equal_to< | |
442 | typename Seq::tuple_size, | |
443 | boost::mpl::int_<0> | |
444 | >::type type; | |
445 | static type call(Seq& seq) { return type(); } | |
446 | }; | |
447 | template<class Seq, class N> | |
448 | struct at : ::boost::type_erasure::detail::get_impl<N::value, Seq> {}; | |
449 | template<class Seq, class N> | |
450 | struct value_at | |
451 | { | |
452 | typedef typename ::boost::type_erasure::detail::get_impl< | |
453 | N::value, | |
454 | Seq | |
455 | >::value_type type; | |
456 | }; | |
457 | }; | |
458 | ||
459 | template<class Concept, | |
460 | BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( | |
461 | BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, class T, ::boost::type_erasure::na)> | |
462 | class tuple; | |
463 | ||
464 | template< | |
465 | int N, | |
466 | class Concept | |
467 | BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, class T) | |
468 | > | |
469 | typename detail::get_impl< | |
470 | N, | |
471 | tuple< | |
472 | Concept | |
473 | BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) | |
474 | > | |
475 | >::type get( | |
476 | tuple< | |
477 | Concept | |
478 | BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) | |
479 | >& arg) | |
480 | { | |
481 | return detail::get_impl< | |
482 | N, | |
483 | tuple< | |
484 | Concept | |
485 | BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) | |
486 | > | |
487 | >::call(arg); | |
488 | } | |
489 | ||
490 | template< | |
491 | int N, | |
492 | class Concept | |
493 | BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, class T) | |
494 | > | |
495 | typename detail::get_impl< | |
496 | N, | |
497 | const tuple< | |
498 | Concept | |
499 | BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) | |
500 | > | |
501 | >::type get( | |
502 | const tuple< | |
503 | Concept | |
504 | BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) | |
505 | >& arg) | |
506 | { | |
507 | return detail::get_impl< | |
508 | N, | |
509 | const tuple< | |
510 | Concept | |
511 | BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE, T) | |
512 | > | |
513 | >::call(arg); | |
514 | } | |
515 | ||
516 | /** INTERNAL ONLY */ | |
517 | #define BOOST_PP_FILENAME_1 <boost/type_erasure/tuple.hpp> | |
518 | /** INTERNAL ONLY */ | |
519 | #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE) | |
520 | #include BOOST_PP_ITERATE() | |
521 | ||
522 | } | |
523 | } | |
524 | ||
525 | #endif | |
526 | ||
527 | #endif | |
528 | ||
529 | #else | |
530 | ||
531 | #define N BOOST_PP_ITERATION() | |
532 | ||
533 | #define BOOST_TYPE_ERASURE_TAG_TYPEDEF(z, n, data) \ | |
534 | typedef BOOST_PP_CAT(T, n) BOOST_PP_CAT(tag_type, n); \ | |
535 | typedef typename ::boost::remove_reference<BOOST_PP_CAT(T, n)>::type \ | |
536 | BOOST_PP_CAT(tag, n); | |
537 | ||
538 | #define BOOST_TYPE_ERASURE_PAIR(z, n, data) \ | |
539 | ::boost::mpl::pair<BOOST_PP_CAT(tag, n), BOOST_PP_CAT(U, n)> | |
540 | ||
541 | #define BOOST_TYPE_ERASURE_CONSTRUCT(z, n, data)\ | |
542 | BOOST_PP_CAT(t, n)(BOOST_PP_CAT(u, n), table) | |
543 | ||
544 | #define BOOST_TYPE_ERASURE_TUPLE_MEMBER(z, n, data)\ | |
545 | ::boost::type_erasure::any<Concept, BOOST_PP_CAT(T, n)> BOOST_PP_CAT(t, n); | |
546 | ||
547 | #if N == 1 | |
548 | #define BOOST_TYPE_ERASURE_EXPLICIT explicit | |
549 | #else | |
550 | #define BOOST_TYPE_ERASURE_EXPLICIT | |
551 | #endif | |
552 | ||
553 | namespace detail { | |
554 | ||
555 | template<class Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> | |
556 | struct tuple_storage | |
557 | #if N != BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE | |
558 | <Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, T)> | |
559 | #endif | |
560 | { | |
561 | #if N | |
562 | template<class Table BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)> | |
563 | tuple_storage( | |
564 | const Table& table BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, &u)) | |
565 | : | |
566 | BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_CONSTRUCT, ~) {} | |
567 | #else | |
568 | template<class Table> | |
569 | explicit tuple_storage(const Table&) {} | |
570 | #endif | |
571 | BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_TUPLE_MEMBER, `) | |
572 | }; | |
573 | ||
574 | #if N != BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE | |
575 | ||
576 | template<class Tuple> | |
577 | struct get_impl<N, Tuple> | |
578 | { | |
579 | typedef any< | |
580 | typename Tuple::concept_type, | |
581 | typename Tuple::BOOST_PP_CAT(tag_type, N) | |
582 | > value_type; | |
583 | typedef value_type& type; | |
584 | static type call(Tuple& arg) | |
585 | { return arg.impl.BOOST_PP_CAT(t, N); } | |
586 | }; | |
587 | ||
588 | template<class Tuple> | |
589 | struct get_impl<N, const Tuple> | |
590 | { | |
591 | typedef any< | |
592 | typename Tuple::concept_type, | |
593 | typename Tuple::BOOST_PP_CAT(tag_type, N) | |
594 | > value_type; | |
595 | typedef const value_type& type; | |
596 | static type call(const Tuple& arg) | |
597 | { return arg.impl.BOOST_PP_CAT(t, N); } | |
598 | }; | |
599 | ||
600 | #endif | |
601 | ||
602 | } | |
603 | ||
604 | template<class Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)> | |
605 | class tuple | |
606 | #if N != BOOST_TYPE_ERASURE_MAX_TUPLE_SIZE | |
607 | <Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, T)> | |
608 | #endif | |
609 | : public tuple_base<tuple<Concept BOOST_PP_ENUM_TRAILING_PARAMS(N, T)> > | |
610 | { | |
611 | typedef Concept concept_type; | |
612 | BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_TAG_TYPEDEF, ~) | |
613 | public: | |
614 | typedef ::boost::mpl::int_<N> tuple_size; | |
615 | #if N | |
616 | template<BOOST_PP_ENUM_PARAMS(N, class U)> | |
617 | #endif | |
618 | BOOST_TYPE_ERASURE_EXPLICIT | |
619 | tuple(BOOST_PP_ENUM_BINARY_PARAMS(N, U, &u)) : | |
620 | impl( | |
621 | ::boost::type_erasure::make_binding< | |
622 | ::boost::mpl::map< | |
623 | BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_PAIR, ~) | |
624 | > | |
625 | >() | |
626 | BOOST_PP_ENUM_TRAILING_PARAMS(N, u) | |
627 | ) | |
628 | {} | |
629 | #if N | |
630 | template<BOOST_PP_ENUM_PARAMS(N, class U)> | |
631 | BOOST_TYPE_ERASURE_EXPLICIT | |
632 | tuple(BOOST_PP_ENUM_BINARY_PARAMS(N, const U, &u)) : | |
633 | impl( | |
634 | ::boost::type_erasure::make_binding< | |
635 | ::boost::mpl::map< | |
636 | BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_PAIR, ~) | |
637 | > | |
638 | >() | |
639 | BOOST_PP_ENUM_TRAILING_PARAMS(N, u) | |
640 | ) | |
641 | {} | |
642 | #endif | |
643 | private: | |
644 | template<int M, class Tuple> | |
645 | friend struct ::boost::type_erasure::detail::get_impl; | |
646 | ::boost::type_erasure::detail::tuple_storage< | |
647 | Concept | |
648 | BOOST_PP_ENUM_TRAILING_PARAMS(N, T) | |
649 | > impl; | |
650 | }; | |
651 | ||
652 | #undef BOOST_TYPE_ERASURE_EXPLICIT | |
653 | #undef BOOST_TYPE_ERASURE_TUPLE_MEMBER | |
654 | #undef BOOST_TYPE_ERASURE_CONSTRUCT | |
655 | #undef BOOST_TYPE_ERASURE_PAIR | |
656 | #undef BOOST_TYPE_ERASURE_TAG_TYPEDEF | |
657 | #undef N | |
658 | ||
659 | #endif |