Line data Source code
1 : // tuple_basic.hpp -----------------------------------------------------
2 :
3 : // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
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 : // For more information, see http://www.boost.org
10 :
11 : // Outside help:
12 : // This and that, Gary Powell.
13 : // Fixed return types for get_head/get_tail
14 : // ( and other bugs ) per suggestion of Jens Maurer
15 : // simplified element type accessors + bug fix (Jeremy Siek)
16 : // Several changes/additions according to suggestions by Douglas Gregor,
17 : // William Kempf, Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes,
18 : // David Abrahams.
19 :
20 : // Revision history:
21 : // 2002 05 01 Hugo Duncan: Fix for Borland after Jaakko's previous changes
22 : // 2002 04 18 Jaakko: tuple element types can be void or plain function
23 : // types, as long as no object is created.
24 : // Tuple objects can no hold even noncopyable types
25 : // such as arrays.
26 : // 2001 10 22 John Maddock
27 : // Fixes for Borland C++
28 : // 2001 08 30 David Abrahams
29 : // Added default constructor for cons<>.
30 : // -----------------------------------------------------------------
31 :
32 : #ifndef BOOST_TUPLE_BASIC_HPP
33 : #define BOOST_TUPLE_BASIC_HPP
34 :
35 :
36 : #include <utility> // needed for the assignment from pair to tuple
37 : #include <cstddef> // for std::size_t
38 :
39 : #include <boost/core/invoke_swap.hpp>
40 : #include <boost/core/ref.hpp>
41 : #include <boost/type_traits/cv_traits.hpp>
42 : #include <boost/type_traits/function_traits.hpp>
43 : #include <boost/type_traits/integral_constant.hpp>
44 :
45 : #include <boost/detail/workaround.hpp> // needed for BOOST_WORKAROUND
46 :
47 : #if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
48 : #pragma GCC diagnostic push
49 : #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
50 : #endif
51 :
52 : namespace boost {
53 : namespace tuples {
54 :
55 : // -- null_type --------------------------------------------------------
56 : struct null_type {};
57 :
58 : // a helper function to provide a const null_type type temporary
59 : namespace detail {
60 : inline const null_type cnull() { return null_type(); }
61 :
62 :
63 : // -- if construct ------------------------------------------------
64 : // Proposed by Krzysztof Czarnecki and Ulrich Eisenecker
65 :
66 : template <bool If, class Then, class Else> struct IF { typedef Then RET; };
67 :
68 : template <class Then, class Else> struct IF<false, Then, Else> {
69 : typedef Else RET;
70 : };
71 :
72 : } // end detail
73 :
74 : // - cons forward declaration -----------------------------------------------
75 : template <class HT, class TT> struct cons;
76 :
77 :
78 : // - tuple forward declaration -----------------------------------------------
79 : template <
80 : class T0 = null_type, class T1 = null_type, class T2 = null_type,
81 : class T3 = null_type, class T4 = null_type, class T5 = null_type,
82 : class T6 = null_type, class T7 = null_type, class T8 = null_type,
83 : class T9 = null_type>
84 : class tuple;
85 :
86 : // tuple_length forward declaration
87 : template<class T> struct length;
88 :
89 :
90 :
91 : namespace detail {
92 :
93 : // -- generate error template, referencing to non-existing members of this
94 : // template is used to produce compilation errors intentionally
95 : template<class T>
96 : class generate_error;
97 :
98 : template<std::size_t N>
99 : struct drop_front {
100 : template<class Tuple>
101 : struct apply {
102 : typedef BOOST_DEDUCED_TYPENAME drop_front<N-1>::BOOST_NESTED_TEMPLATE
103 : apply<Tuple> next;
104 : typedef BOOST_DEDUCED_TYPENAME next::type::tail_type type;
105 408911 : static const type& call(const Tuple& tup) {
106 408911 : return next::call(tup).tail;
107 : }
108 : };
109 : };
110 :
111 : template<>
112 : struct drop_front<0> {
113 : template<class Tuple>
114 : struct apply {
115 : typedef Tuple type;
116 433102 : static const type& call(const Tuple& tup) {
117 433102 : return tup;
118 : }
119 : };
120 : };
121 :
122 : } // end of namespace detail
123 :
124 :
125 : // -cons type accessors ----------------------------------------
126 : // typename tuples::element<N,T>::type gets the type of the
127 : // Nth element ot T, first element is at index 0
128 : // -------------------------------------------------------
129 :
130 : #ifndef BOOST_NO_CV_SPECIALIZATIONS
131 :
132 : template<std::size_t N, class T>
133 : struct element
134 : {
135 : typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
136 : apply<T>::type::head_type type;
137 : };
138 :
139 : template<std::size_t N, class T>
140 : struct element<N, const T>
141 : {
142 : private:
143 : typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
144 : apply<T>::type::head_type unqualified_type;
145 : public:
146 : #if BOOST_WORKAROUND(BOOST_BORLANDC,<0x600)
147 : typedef const unqualified_type type;
148 : #else
149 : typedef BOOST_DEDUCED_TYPENAME boost::add_const<unqualified_type>::type type;
150 : #endif
151 : };
152 : #else // def BOOST_NO_CV_SPECIALIZATIONS
153 :
154 : namespace detail {
155 :
156 : template<std::size_t N, class T, bool IsConst>
157 : struct element_impl
158 : {
159 : typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
160 : apply<T>::type::head_type type;
161 : };
162 :
163 : template<std::size_t N, class T>
164 : struct element_impl<N, T, true /* IsConst */>
165 : {
166 : typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
167 : apply<T>::type::head_type unqualified_type;
168 : typedef const unqualified_type type;
169 : };
170 :
171 : } // end of namespace detail
172 :
173 :
174 : template<std::size_t N, class T>
175 : struct element:
176 : public detail::element_impl<N, T, ::boost::is_const<T>::value>
177 : {
178 : };
179 :
180 : #endif
181 :
182 :
183 : // -get function templates -----------------------------------------------
184 : // Usage: get<N>(aTuple)
185 :
186 : // -- some traits classes for get functions
187 :
188 : // access traits lifted from detail namespace to be part of the interface,
189 : // (Joel de Guzman's suggestion). Rationale: get functions are part of the
190 : // interface, so should the way to express their return types be.
191 :
192 : template <class T> struct access_traits {
193 : typedef const T& const_type;
194 : typedef T& non_const_type;
195 :
196 : typedef const typename boost::remove_cv<T>::type& parameter_type;
197 :
198 : // used as the tuple constructors parameter types
199 : // Rationale: non-reference tuple element types can be cv-qualified.
200 : // It should be possible to initialize such types with temporaries,
201 : // and when binding temporaries to references, the reference must
202 : // be non-volatile and const. 8.5.3. (5)
203 : };
204 :
205 : template <class T> struct access_traits<T&> {
206 :
207 : typedef T& const_type;
208 : typedef T& non_const_type;
209 :
210 : typedef T& parameter_type;
211 : };
212 :
213 : // get function for non-const cons-lists, returns a reference to the element
214 :
215 : template<std::size_t N, class HT, class TT>
216 : inline typename access_traits<
217 : typename element<N, cons<HT, TT> >::type
218 : >::non_const_type
219 : get(cons<HT, TT>& c) {
220 : typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
221 : apply<cons<HT, TT> > impl;
222 : typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
223 : return const_cast<cons_element&>(impl::call(c)).head;
224 : }
225 :
226 : // get function for const cons-lists, returns a const reference to
227 : // the element. If the element is a reference, returns the reference
228 : // as such (that is, can return a non-const reference)
229 : template<std::size_t N, class HT, class TT>
230 : inline typename access_traits<
231 : typename element<N, cons<HT, TT> >::type
232 : >::const_type
233 433102 : get(const cons<HT, TT>& c) {
234 : typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
235 : apply<cons<HT, TT> > impl;
236 433102 : return impl::call(c).head;
237 : }
238 :
239 : // -- the cons template --------------------------------------------------
240 : namespace detail {
241 :
242 : // These helper templates wrap void types and plain function types.
243 : // The reationale is to allow one to write tuple types with those types
244 : // as elements, even though it is not possible to instantiate such object.
245 : // E.g: typedef tuple<void> some_type; // ok
246 : // but: some_type x; // fails
247 :
248 : template <class T> class non_storeable_type {
249 : non_storeable_type();
250 : };
251 :
252 : template <class T> struct wrap_non_storeable_type {
253 : typedef typename IF<
254 : ::boost::is_function<T>::value, non_storeable_type<T>, T
255 : >::RET type;
256 : };
257 : template <> struct wrap_non_storeable_type<void> {
258 : typedef non_storeable_type<void> type;
259 : };
260 :
261 : } // detail
262 :
263 : template <class HT, class TT>
264 : struct cons {
265 :
266 : typedef HT head_type;
267 : typedef TT tail_type;
268 :
269 : typedef typename
270 : detail::wrap_non_storeable_type<head_type>::type stored_head_type;
271 :
272 : stored_head_type head;
273 : tail_type tail;
274 :
275 : typename access_traits<stored_head_type>::non_const_type
276 : get_head() { return head; }
277 :
278 : typename access_traits<tail_type>::non_const_type
279 : get_tail() { return tail; }
280 :
281 : typename access_traits<stored_head_type>::const_type
282 336510 : get_head() const { return head; }
283 :
284 : typename access_traits<tail_type>::const_type
285 120165 : get_tail() const { return tail; }
286 :
287 601151 : cons() : head(), tail() {}
288 : // cons() : head(detail::default_arg<HT>::f()), tail() {}
289 :
290 : // the argument for head is not strictly needed, but it prevents
291 : // array type elements. This is good, since array type elements
292 : // cannot be supported properly in any case (no assignment,
293 : // copy works only if the tails are exactly the same type, ...)
294 :
295 : cons(typename access_traits<stored_head_type>::parameter_type h,
296 : const tail_type& t)
297 : : head (h), tail(t) {}
298 :
299 : template <class T1, class T2, class T3, class T4, class T5,
300 : class T6, class T7, class T8, class T9, class T10>
301 : cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
302 : T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
303 : : head (t1),
304 : tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
305 : {}
306 :
307 : template <class T2, class T3, class T4, class T5,
308 : class T6, class T7, class T8, class T9, class T10>
309 : cons( const null_type& /*t1*/, T2& t2, T3& t3, T4& t4, T5& t5,
310 : T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
311 : : head (),
312 : tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
313 : {}
314 :
315 : cons( const cons& u ) : head(u.head), tail(u.tail) {}
316 :
317 : template <class HT2, class TT2>
318 : cons( const cons<HT2, TT2>& u ) : head(u.head), tail(u.tail) {}
319 :
320 : template <class HT2, class TT2>
321 : cons& operator=( const cons<HT2, TT2>& u ) {
322 : head=u.head; tail=u.tail; return *this;
323 : }
324 :
325 : // must define assignment operator explicitly, implicit version is
326 : // illformed if HT is a reference (12.8. (12))
327 : cons& operator=(const cons& u) {
328 : head = u.head; tail = u.tail; return *this;
329 : }
330 :
331 : template <class T1, class T2>
332 : cons& operator=( const std::pair<T1, T2>& u ) {
333 : BOOST_STATIC_ASSERT(length<cons>::value == 2); // check length = 2
334 : head = u.first; tail.head = u.second; return *this;
335 : }
336 :
337 : // get member functions (non-const and const)
338 : template <std::size_t N>
339 : typename access_traits<
340 : typename element<N, cons<HT, TT> >::type
341 : >::non_const_type
342 : get() {
343 : return boost::tuples::get<N>(*this); // delegate to non-member get
344 : }
345 :
346 : template <std::size_t N>
347 : typename access_traits<
348 : typename element<N, cons<HT, TT> >::type
349 : >::const_type
350 : get() const {
351 : return boost::tuples::get<N>(*this); // delegate to non-member get
352 : }
353 : };
354 :
355 : template <class HT>
356 : struct cons<HT, null_type> {
357 :
358 : typedef HT head_type;
359 : typedef null_type tail_type;
360 : typedef cons<HT, null_type> self_type;
361 :
362 : typedef typename
363 : detail::wrap_non_storeable_type<head_type>::type stored_head_type;
364 : stored_head_type head;
365 :
366 : typename access_traits<stored_head_type>::non_const_type
367 : get_head() { return head; }
368 :
369 : null_type get_tail() { return null_type(); }
370 :
371 : typename access_traits<stored_head_type>::const_type
372 96592 : get_head() const { return head; }
373 :
374 72607 : const null_type get_tail() const { return null_type(); }
375 :
376 : // cons() : head(detail::default_arg<HT>::f()) {}
377 482136 : cons() : head() {}
378 :
379 : cons(typename access_traits<stored_head_type>::parameter_type h,
380 : const null_type& = null_type())
381 : : head (h) {}
382 :
383 : template<class T1>
384 : cons(T1& t1, const null_type&, const null_type&, const null_type&,
385 : const null_type&, const null_type&, const null_type&,
386 : const null_type&, const null_type&, const null_type&)
387 : : head (t1) {}
388 :
389 : cons(const null_type&,
390 : const null_type&, const null_type&, const null_type&,
391 : const null_type&, const null_type&, const null_type&,
392 : const null_type&, const null_type&, const null_type&)
393 : : head () {}
394 :
395 : cons( const cons& u ) : head(u.head) {}
396 :
397 : template <class HT2>
398 : cons( const cons<HT2, null_type>& u ) : head(u.head) {}
399 :
400 : template <class HT2>
401 : cons& operator=(const cons<HT2, null_type>& u )
402 : { head = u.head; return *this; }
403 :
404 : // must define assignment operator explicitely, implicit version
405 : // is illformed if HT is a reference
406 : cons& operator=(const cons& u) { head = u.head; return *this; }
407 :
408 : template <std::size_t N>
409 : typename access_traits<
410 : typename element<N, self_type>::type
411 : >::non_const_type
412 : get() {
413 : return boost::tuples::get<N>(*this);
414 : }
415 :
416 : template <std::size_t N>
417 : typename access_traits<
418 : typename element<N, self_type>::type
419 : >::const_type
420 : get() const {
421 : return boost::tuples::get<N>(*this);
422 : }
423 :
424 : };
425 :
426 : // templates for finding out the length of the tuple -------------------
427 :
428 : template<class T>
429 : struct length: boost::integral_constant<std::size_t, 1 + length<typename T::tail_type>::value>
430 : {
431 : };
432 :
433 : template<>
434 : struct length<tuple<> >: boost::integral_constant<std::size_t, 0>
435 : {
436 : };
437 :
438 : template<>
439 : struct length<tuple<> const>: boost::integral_constant<std::size_t, 0>
440 : {
441 : };
442 :
443 : template<>
444 : struct length<null_type>: boost::integral_constant<std::size_t, 0>
445 : {
446 : };
447 :
448 : template<>
449 : struct length<null_type const>: boost::integral_constant<std::size_t, 0>
450 : {
451 : };
452 :
453 : namespace detail {
454 :
455 : // Tuple to cons mapper --------------------------------------------------
456 : template <class T0, class T1, class T2, class T3, class T4,
457 : class T5, class T6, class T7, class T8, class T9>
458 : struct map_tuple_to_cons
459 : {
460 : typedef cons<T0,
461 : typename map_tuple_to_cons<T1, T2, T3, T4, T5,
462 : T6, T7, T8, T9, null_type>::type
463 : > type;
464 : };
465 :
466 : // The empty tuple is a null_type
467 : template <>
468 : struct map_tuple_to_cons<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type>
469 : {
470 : typedef null_type type;
471 : };
472 :
473 : } // end detail
474 :
475 : // -------------------------------------------------------------------
476 : // -- tuple ------------------------------------------------------
477 : template <class T0, class T1, class T2, class T3, class T4,
478 : class T5, class T6, class T7, class T8, class T9>
479 :
480 : class tuple :
481 : public detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
482 : {
483 : public:
484 : typedef typename
485 : detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type inherited;
486 : typedef typename inherited::head_type head_type;
487 : typedef typename inherited::tail_type tail_type;
488 :
489 :
490 : // access_traits<T>::parameter_type takes non-reference types as const T&
491 336922 : tuple() {}
492 :
493 : explicit tuple(typename access_traits<T0>::parameter_type t0)
494 : : inherited(t0, detail::cnull(), detail::cnull(), detail::cnull(),
495 : detail::cnull(), detail::cnull(), detail::cnull(),
496 : detail::cnull(), detail::cnull(), detail::cnull()) {}
497 :
498 : tuple(typename access_traits<T0>::parameter_type t0,
499 : typename access_traits<T1>::parameter_type t1)
500 : : inherited(t0, t1, detail::cnull(), detail::cnull(),
501 : detail::cnull(), detail::cnull(), detail::cnull(),
502 : detail::cnull(), detail::cnull(), detail::cnull()) {}
503 :
504 : tuple(typename access_traits<T0>::parameter_type t0,
505 : typename access_traits<T1>::parameter_type t1,
506 : typename access_traits<T2>::parameter_type t2)
507 : : inherited(t0, t1, t2, detail::cnull(), detail::cnull(),
508 : detail::cnull(), detail::cnull(), detail::cnull(),
509 : detail::cnull(), detail::cnull()) {}
510 :
511 : tuple(typename access_traits<T0>::parameter_type t0,
512 : typename access_traits<T1>::parameter_type t1,
513 : typename access_traits<T2>::parameter_type t2,
514 : typename access_traits<T3>::parameter_type t3)
515 : : inherited(t0, t1, t2, t3, detail::cnull(), detail::cnull(),
516 : detail::cnull(), detail::cnull(), detail::cnull(),
517 : detail::cnull()) {}
518 :
519 : tuple(typename access_traits<T0>::parameter_type t0,
520 : typename access_traits<T1>::parameter_type t1,
521 : typename access_traits<T2>::parameter_type t2,
522 : typename access_traits<T3>::parameter_type t3,
523 : typename access_traits<T4>::parameter_type t4)
524 : : inherited(t0, t1, t2, t3, t4, detail::cnull(), detail::cnull(),
525 : detail::cnull(), detail::cnull(), detail::cnull()) {}
526 :
527 : tuple(typename access_traits<T0>::parameter_type t0,
528 : typename access_traits<T1>::parameter_type t1,
529 : typename access_traits<T2>::parameter_type t2,
530 : typename access_traits<T3>::parameter_type t3,
531 : typename access_traits<T4>::parameter_type t4,
532 : typename access_traits<T5>::parameter_type t5)
533 : : inherited(t0, t1, t2, t3, t4, t5, detail::cnull(), detail::cnull(),
534 : detail::cnull(), detail::cnull()) {}
535 :
536 : tuple(typename access_traits<T0>::parameter_type t0,
537 : typename access_traits<T1>::parameter_type t1,
538 : typename access_traits<T2>::parameter_type t2,
539 : typename access_traits<T3>::parameter_type t3,
540 : typename access_traits<T4>::parameter_type t4,
541 : typename access_traits<T5>::parameter_type t5,
542 : typename access_traits<T6>::parameter_type t6)
543 : : inherited(t0, t1, t2, t3, t4, t5, t6, detail::cnull(),
544 : detail::cnull(), detail::cnull()) {}
545 :
546 : tuple(typename access_traits<T0>::parameter_type t0,
547 : typename access_traits<T1>::parameter_type t1,
548 : typename access_traits<T2>::parameter_type t2,
549 : typename access_traits<T3>::parameter_type t3,
550 : typename access_traits<T4>::parameter_type t4,
551 : typename access_traits<T5>::parameter_type t5,
552 : typename access_traits<T6>::parameter_type t6,
553 : typename access_traits<T7>::parameter_type t7)
554 : : inherited(t0, t1, t2, t3, t4, t5, t6, t7, detail::cnull(),
555 : detail::cnull()) {}
556 :
557 : tuple(typename access_traits<T0>::parameter_type t0,
558 : typename access_traits<T1>::parameter_type t1,
559 : typename access_traits<T2>::parameter_type t2,
560 : typename access_traits<T3>::parameter_type t3,
561 : typename access_traits<T4>::parameter_type t4,
562 : typename access_traits<T5>::parameter_type t5,
563 : typename access_traits<T6>::parameter_type t6,
564 : typename access_traits<T7>::parameter_type t7,
565 : typename access_traits<T8>::parameter_type t8)
566 : : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, detail::cnull()) {}
567 :
568 : tuple(typename access_traits<T0>::parameter_type t0,
569 : typename access_traits<T1>::parameter_type t1,
570 : typename access_traits<T2>::parameter_type t2,
571 : typename access_traits<T3>::parameter_type t3,
572 : typename access_traits<T4>::parameter_type t4,
573 : typename access_traits<T5>::parameter_type t5,
574 : typename access_traits<T6>::parameter_type t6,
575 : typename access_traits<T7>::parameter_type t7,
576 : typename access_traits<T8>::parameter_type t8,
577 : typename access_traits<T9>::parameter_type t9)
578 : : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {}
579 :
580 :
581 : template<class U1, class U2>
582 : tuple(const cons<U1, U2>& p) : inherited(p) {}
583 :
584 : template <class U1, class U2>
585 : tuple& operator=(const cons<U1, U2>& k) {
586 : inherited::operator=(k);
587 : return *this;
588 : }
589 :
590 : template <class U1, class U2>
591 : tuple& operator=(const std::pair<U1, U2>& k) {
592 : BOOST_STATIC_ASSERT(length<tuple>::value == 2);// check_length = 2
593 : this->head = k.first;
594 : this->tail.head = k.second;
595 : return *this;
596 : }
597 :
598 : };
599 :
600 : // The empty tuple
601 : template <>
602 : class tuple<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> :
603 : public null_type
604 : {
605 : public:
606 : typedef null_type inherited;
607 : };
608 :
609 :
610 : // Swallows any assignment (by Doug Gregor)
611 : namespace detail {
612 :
613 : struct swallow_assign;
614 : typedef void (detail::swallow_assign::*ignore_t)();
615 : struct swallow_assign {
616 : swallow_assign(ignore_t(*)(ignore_t)) {}
617 : template<typename T>
618 : swallow_assign const& operator=(const T&) const {
619 : return *this;
620 : }
621 : };
622 :
623 :
624 : } // namespace detail
625 :
626 : // "ignore" allows tuple positions to be ignored when using "tie".
627 : inline detail::ignore_t ignore(detail::ignore_t) { return 0; }
628 :
629 : // ---------------------------------------------------------------------------
630 : // The call_traits for make_tuple
631 : // Honours the reference_wrapper class.
632 :
633 : // Must be instantiated with plain or const plain types (not with references)
634 :
635 : // from template<class T> foo(const T& t) : make_tuple_traits<const T>::type
636 : // from template<class T> foo(T& t) : make_tuple_traits<T>::type
637 :
638 : // Conversions:
639 : // T -> T,
640 : // references -> compile_time_error
641 : // reference_wrapper<T> -> T&
642 : // const reference_wrapper<T> -> T&
643 : // array -> const ref array
644 :
645 :
646 : template<class T>
647 : struct make_tuple_traits {
648 : typedef T type;
649 :
650 : // commented away, see below (JJ)
651 : // typedef typename IF<
652 : // boost::is_function<T>::value,
653 : // T&,
654 : // T>::RET type;
655 :
656 : };
657 :
658 : // The is_function test was there originally for plain function types,
659 : // which can't be stored as such (we must either store them as references or
660 : // pointers). Such a type could be formed if make_tuple was called with a
661 : // reference to a function.
662 : // But this would mean that a const qualified function type was formed in
663 : // the make_tuple function and hence make_tuple can't take a function
664 : // reference as a parameter, and thus T can't be a function type.
665 : // So is_function test was removed.
666 : // (14.8.3. says that type deduction fails if a cv-qualified function type
667 : // is created. (It only applies for the case of explicitly specifying template
668 : // args, though?)) (JJ)
669 :
670 : template<class T>
671 : struct make_tuple_traits<T&> {
672 : typedef typename
673 : detail::generate_error<T&>::
674 : do_not_use_with_reference_type error;
675 : };
676 :
677 : // Arrays can't be stored as plain types; convert them to references.
678 : // All arrays are converted to const. This is because make_tuple takes its
679 : // parameters as const T& and thus the knowledge of the potential
680 : // non-constness of actual argument is lost.
681 : template<class T, std::size_t n> struct make_tuple_traits <T[n]> {
682 : typedef const T (&type)[n];
683 : };
684 :
685 : template<class T, std::size_t n>
686 : struct make_tuple_traits<const T[n]> {
687 : typedef const T (&type)[n];
688 : };
689 :
690 : template<class T, std::size_t n> struct make_tuple_traits<volatile T[n]> {
691 : typedef const volatile T (&type)[n];
692 : };
693 :
694 : template<class T, std::size_t n>
695 : struct make_tuple_traits<const volatile T[n]> {
696 : typedef const volatile T (&type)[n];
697 : };
698 :
699 : template<class T>
700 : struct make_tuple_traits<reference_wrapper<T> >{
701 : typedef T& type;
702 : };
703 :
704 : template<class T>
705 : struct make_tuple_traits<const reference_wrapper<T> >{
706 : typedef T& type;
707 : };
708 :
709 : template<>
710 : struct make_tuple_traits<detail::ignore_t(detail::ignore_t)> {
711 : typedef detail::swallow_assign type;
712 : };
713 :
714 :
715 :
716 : namespace detail {
717 :
718 : // a helper traits to make the make_tuple functions shorter (Vesa Karvonen's
719 : // suggestion)
720 : template <
721 : class T0 = null_type, class T1 = null_type, class T2 = null_type,
722 : class T3 = null_type, class T4 = null_type, class T5 = null_type,
723 : class T6 = null_type, class T7 = null_type, class T8 = null_type,
724 : class T9 = null_type
725 : >
726 : struct make_tuple_mapper {
727 : typedef
728 : tuple<typename make_tuple_traits<T0>::type,
729 : typename make_tuple_traits<T1>::type,
730 : typename make_tuple_traits<T2>::type,
731 : typename make_tuple_traits<T3>::type,
732 : typename make_tuple_traits<T4>::type,
733 : typename make_tuple_traits<T5>::type,
734 : typename make_tuple_traits<T6>::type,
735 : typename make_tuple_traits<T7>::type,
736 : typename make_tuple_traits<T8>::type,
737 : typename make_tuple_traits<T9>::type> type;
738 : };
739 :
740 : } // end detail
741 :
742 : // -make_tuple function templates -----------------------------------
743 : inline tuple<> make_tuple() {
744 : return tuple<>();
745 : }
746 :
747 : template<class T0>
748 : inline typename detail::make_tuple_mapper<T0>::type
749 : make_tuple(const T0& t0) {
750 : typedef typename detail::make_tuple_mapper<T0>::type t;
751 : return t(t0);
752 : }
753 :
754 : template<class T0, class T1>
755 : inline typename detail::make_tuple_mapper<T0, T1>::type
756 : make_tuple(const T0& t0, const T1& t1) {
757 : typedef typename detail::make_tuple_mapper<T0, T1>::type t;
758 : return t(t0, t1);
759 : }
760 :
761 : template<class T0, class T1, class T2>
762 : inline typename detail::make_tuple_mapper<T0, T1, T2>::type
763 : make_tuple(const T0& t0, const T1& t1, const T2& t2) {
764 : typedef typename detail::make_tuple_mapper<T0, T1, T2>::type t;
765 : return t(t0, t1, t2);
766 : }
767 :
768 : template<class T0, class T1, class T2, class T3>
769 : inline typename detail::make_tuple_mapper<T0, T1, T2, T3>::type
770 : make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3) {
771 : typedef typename detail::make_tuple_mapper<T0, T1, T2, T3>::type t;
772 : return t(t0, t1, t2, t3);
773 : }
774 :
775 : template<class T0, class T1, class T2, class T3, class T4>
776 : inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type
777 : make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
778 : const T4& t4) {
779 : typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type t;
780 : return t(t0, t1, t2, t3, t4);
781 : }
782 :
783 : template<class T0, class T1, class T2, class T3, class T4, class T5>
784 : inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type
785 : make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
786 : const T4& t4, const T5& t5) {
787 : typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type t;
788 : return t(t0, t1, t2, t3, t4, t5);
789 : }
790 :
791 : template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
792 : inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6>::type
793 : make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
794 : const T4& t4, const T5& t5, const T6& t6) {
795 : typedef typename detail::make_tuple_mapper
796 : <T0, T1, T2, T3, T4, T5, T6>::type t;
797 : return t(t0, t1, t2, t3, t4, t5, t6);
798 : }
799 :
800 : template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
801 : class T7>
802 : inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
803 : make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
804 : const T4& t4, const T5& t5, const T6& t6, const T7& t7) {
805 : typedef typename detail::make_tuple_mapper
806 : <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
807 : return t(t0, t1, t2, t3, t4, t5, t6, t7);
808 : }
809 :
810 : template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
811 : class T7, class T8>
812 : inline typename detail::make_tuple_mapper
813 : <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
814 : make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
815 : const T4& t4, const T5& t5, const T6& t6, const T7& t7,
816 : const T8& t8) {
817 : typedef typename detail::make_tuple_mapper
818 : <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
819 : return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
820 : }
821 :
822 : template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
823 : class T7, class T8, class T9>
824 : inline typename detail::make_tuple_mapper
825 : <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
826 : make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
827 : const T4& t4, const T5& t5, const T6& t6, const T7& t7,
828 : const T8& t8, const T9& t9) {
829 : typedef typename detail::make_tuple_mapper
830 : <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
831 : return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
832 : }
833 :
834 : namespace detail {
835 :
836 : template<class T>
837 : struct tie_traits {
838 : typedef T& type;
839 : };
840 :
841 : template<>
842 : struct tie_traits<ignore_t(ignore_t)> {
843 : typedef swallow_assign type;
844 : };
845 :
846 : template<>
847 : struct tie_traits<void> {
848 : typedef null_type type;
849 : };
850 :
851 : template <
852 : class T0 = void, class T1 = void, class T2 = void,
853 : class T3 = void, class T4 = void, class T5 = void,
854 : class T6 = void, class T7 = void, class T8 = void,
855 : class T9 = void
856 : >
857 : struct tie_mapper {
858 : typedef
859 : tuple<typename tie_traits<T0>::type,
860 : typename tie_traits<T1>::type,
861 : typename tie_traits<T2>::type,
862 : typename tie_traits<T3>::type,
863 : typename tie_traits<T4>::type,
864 : typename tie_traits<T5>::type,
865 : typename tie_traits<T6>::type,
866 : typename tie_traits<T7>::type,
867 : typename tie_traits<T8>::type,
868 : typename tie_traits<T9>::type> type;
869 : };
870 :
871 : }
872 :
873 : // Tie function templates -------------------------------------------------
874 : template<class T0>
875 : inline typename detail::tie_mapper<T0>::type
876 : tie(T0& t0) {
877 : typedef typename detail::tie_mapper<T0>::type t;
878 : return t(t0);
879 : }
880 :
881 : template<class T0, class T1>
882 : inline typename detail::tie_mapper<T0, T1>::type
883 : tie(T0& t0, T1& t1) {
884 : typedef typename detail::tie_mapper<T0, T1>::type t;
885 : return t(t0, t1);
886 : }
887 :
888 : template<class T0, class T1, class T2>
889 : inline typename detail::tie_mapper<T0, T1, T2>::type
890 : tie(T0& t0, T1& t1, T2& t2) {
891 : typedef typename detail::tie_mapper<T0, T1, T2>::type t;
892 : return t(t0, t1, t2);
893 : }
894 :
895 : template<class T0, class T1, class T2, class T3>
896 : inline typename detail::tie_mapper<T0, T1, T2, T3>::type
897 : tie(T0& t0, T1& t1, T2& t2, T3& t3) {
898 : typedef typename detail::tie_mapper<T0, T1, T2, T3>::type t;
899 : return t(t0, t1, t2, t3);
900 : }
901 :
902 : template<class T0, class T1, class T2, class T3, class T4>
903 : inline typename detail::tie_mapper<T0, T1, T2, T3, T4>::type
904 : tie(T0& t0, T1& t1, T2& t2, T3& t3,
905 : T4& t4) {
906 : typedef typename detail::tie_mapper<T0, T1, T2, T3, T4>::type t;
907 : return t(t0, t1, t2, t3, t4);
908 : }
909 :
910 : template<class T0, class T1, class T2, class T3, class T4, class T5>
911 : inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type
912 : tie(T0& t0, T1& t1, T2& t2, T3& t3,
913 : T4& t4, T5& t5) {
914 : typedef typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type t;
915 : return t(t0, t1, t2, t3, t4, t5);
916 : }
917 :
918 : template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
919 : inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6>::type
920 : tie(T0& t0, T1& t1, T2& t2, T3& t3,
921 : T4& t4, T5& t5, T6& t6) {
922 : typedef typename detail::tie_mapper
923 : <T0, T1, T2, T3, T4, T5, T6>::type t;
924 : return t(t0, t1, t2, t3, t4, t5, t6);
925 : }
926 :
927 : template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
928 : class T7>
929 : inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
930 : tie(T0& t0, T1& t1, T2& t2, T3& t3,
931 : T4& t4, T5& t5, T6& t6, T7& t7) {
932 : typedef typename detail::tie_mapper
933 : <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
934 : return t(t0, t1, t2, t3, t4, t5, t6, t7);
935 : }
936 :
937 : template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
938 : class T7, class T8>
939 : inline typename detail::tie_mapper
940 : <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
941 : tie(T0& t0, T1& t1, T2& t2, T3& t3,
942 : T4& t4, T5& t5, T6& t6, T7& t7,
943 : T8& t8) {
944 : typedef typename detail::tie_mapper
945 : <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
946 : return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
947 : }
948 :
949 : template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
950 : class T7, class T8, class T9>
951 : inline typename detail::tie_mapper
952 : <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
953 : tie(T0& t0, T1& t1, T2& t2, T3& t3,
954 : T4& t4, T5& t5, T6& t6, T7& t7,
955 : T8& t8, T9& t9) {
956 : typedef typename detail::tie_mapper
957 : <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
958 : return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
959 : }
960 :
961 : template <class T0, class T1, class T2, class T3, class T4,
962 : class T5, class T6, class T7, class T8, class T9>
963 : void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
964 : tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs);
965 : inline void swap(null_type&, null_type&) {}
966 : template<class HH>
967 : inline void swap(cons<HH, null_type>& lhs, cons<HH, null_type>& rhs) {
968 : ::boost::core::invoke_swap(lhs.head, rhs.head);
969 : }
970 : template<class HH, class TT>
971 : inline void swap(cons<HH, TT>& lhs, cons<HH, TT>& rhs) {
972 : ::boost::core::invoke_swap(lhs.head, rhs.head);
973 : ::boost::tuples::swap(lhs.tail, rhs.tail);
974 : }
975 : template <class T0, class T1, class T2, class T3, class T4,
976 : class T5, class T6, class T7, class T8, class T9>
977 : inline void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
978 : tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs) {
979 : typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
980 : typedef typename tuple_type::inherited base;
981 : ::boost::tuples::swap(static_cast<base&>(lhs), static_cast<base&>(rhs));
982 : }
983 :
984 : } // end of namespace tuples
985 : } // end of namespace boost
986 :
987 :
988 : #if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
989 : #pragma GCC diagnostic pop
990 : #endif
991 :
992 :
993 : #endif // BOOST_TUPLE_BASIC_HPP
|