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