]> git.donarmstrong.com Git - rsem.git/blob - boost/tuple/detail/tuple_basic_no_partial_spec.hpp
Updated boost to v1.55.0
[rsem.git] / boost / tuple / detail / tuple_basic_no_partial_spec.hpp
1 // - tuple_basic_no_partial_spec.hpp -----------------------------------------
2
3 // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
4 // Copyright (C) 2001 Douglas Gregor (gregod@rpi.edu)
5 // Copyright (C) 2001 Gary Powell (gary.powell@sierra.com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See
8 // accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10
11 // For more information, see http://www.boost.org or http://lambda.cs.utu.fi
12
13 // Revision History
14 //  14 02 01    Remove extra ';'. Also, fixed 10-parameter to make_tuple. (DG)
15 //  10 02 01    Fixed "null_type" constructors.
16 //              Implemented comparison operators globally.
17 //              Hide element_type_ref and element_type_const_ref.
18 //              (DG).
19 //  09 02 01    Extended to tuples of length 10. Changed comparison for
20 //              operator<()
21 //              to the same used by std::pair<>, added cnull_type() (GP)
22 //  03 02 01    Initial Version from original tuple.hpp code by JJ. (DG)
23
24 // -----------------------------------------------------------------
25
26 #ifndef BOOST_TUPLE_BASIC_NO_PARTIAL_SPEC_HPP
27 #define BOOST_TUPLE_BASIC_NO_PARTIAL_SPEC_HPP
28
29 #include "boost/type_traits.hpp"
30 #include "boost/utility/swap.hpp"
31 #include <utility>
32
33 #if defined BOOST_MSVC
34 #pragma warning(disable:4518) // storage-class or type specifier(s) unexpected here; ignored
35 #pragma warning(disable:4181) // qualifier applied to reference type ignored
36 #pragma warning(disable:4227) // qualifier applied to reference type ignored
37 #endif
38
39 namespace boost {
40 namespace tuples {
41
42     // null_type denotes the end of a list built with "cons"
43     struct null_type
44     {
45       null_type() {}
46       null_type(const null_type&, const null_type&) {}
47     };
48
49     // a helper function to provide a const null_type type temporary
50     inline const null_type cnull_type() { return null_type(); }
51
52 // forward declaration of tuple
53     template<
54       typename T1 = null_type,
55       typename T2 = null_type,
56       typename T3 = null_type,
57       typename T4 = null_type,
58       typename T5 = null_type,
59       typename T6 = null_type,
60       typename T7 = null_type,
61       typename T8 = null_type,
62       typename T9 = null_type,
63       typename T10 = null_type
64     >
65     class tuple;
66
67 // forward declaration of cons
68     template<typename Head, typename Tail = null_type>
69     struct cons;
70
71     namespace detail {
72
73       // Takes a pointer and routes all assignments to whatever it points to
74       template<typename T>
75       struct assign_to_pointee
76       {
77       public:
78         explicit assign_to_pointee(T* p) : ptr(p) {}
79
80         template<typename Other>
81         assign_to_pointee& operator=(const Other& other)
82         {
83           *ptr = other;
84           return *this;
85         }
86
87       private:
88         T* ptr;
89       };
90
91       // Swallows any assignment
92       struct swallow_assign
93       {
94         template<typename T>
95         swallow_assign const& operator=(const T&) const
96         {
97           return *this;
98         }
99       };
100
101     template <typename T> struct add_const_reference : add_reference<typename add_const<T>::type> {};
102
103     template <class MyTail>
104     struct init_tail
105     {
106         // Each of vc6 and vc7 seem to require a different formulation
107         // of this return type
108         template <class H, class T>
109 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
110         static typename add_reference<typename add_const<T>::type>::type
111 #else
112         static typename add_const_reference<T>::type
113 #endif
114         execute( cons<H,T> const& u, long )
115         {
116             return u.get_tail();
117         }
118     };
119
120     template <>
121     struct init_tail<null_type>
122     {
123         template <class H>
124         static null_type execute( cons<H,null_type> const& u, long )
125         {
126             return null_type();
127         }
128
129         template <class U>
130         static null_type execute(U const&, ...)
131         {
132             return null_type();
133         }
134      private:
135         template <class H, class T>
136         void execute( cons<H,T> const&, int);
137     };
138
139     template <class Other>
140     Other const&
141     init_head( Other const& u, ... )
142     {
143         return u;
144     }
145
146     template <class H, class T>
147     typename add_reference<typename add_const<H>::type>::type
148     init_head( cons<H,T> const& u, int )
149     {
150         return u.get_head();
151     }
152
153     inline char**** init_head(null_type const&, int);
154
155   } // end of namespace detail
156
157     // cons builds a heterogenous list of types
158    template<typename Head, typename Tail>
159    struct cons
160    {
161      typedef cons self_type;
162      typedef Head head_type;
163      typedef Tail tail_type;
164
165     private:
166        typedef typename boost::add_reference<head_type>::type head_ref;
167        typedef typename boost::add_reference<tail_type>::type tail_ref;
168        typedef typename detail::add_const_reference<head_type>::type head_cref;
169        typedef typename detail::add_const_reference<tail_type>::type tail_cref;
170     public:
171      head_type head;
172      tail_type tail;
173
174      head_ref get_head() { return head; }
175      tail_ref get_tail() { return tail; }
176
177      head_cref get_head() const { return head; }
178      tail_cref get_tail() const { return tail; }
179
180      cons() : head(), tail() {}
181
182 #if defined BOOST_MSVC
183       template<typename Tail>
184       cons(head_cref h /* = head_type() */, // causes MSVC 6.5 to barf.
185                     const Tail& t) : head(h), tail(t.head, t.tail)
186       {
187       }
188
189       cons(head_cref h /* = head_type() */, // causes MSVC 6.5 to barf.
190                     const null_type& t) : head(h), tail(t)
191       {
192       }
193
194 #else
195       template<typename T>
196       explicit cons(head_cref h, const T& t) :
197         head(h), tail(t.head, t.tail)
198       {
199       }
200
201       explicit cons(head_cref h = head_type(),
202                     tail_cref t = tail_type()) :
203         head(h), tail(t)
204       {
205       }
206 #endif
207
208       template <class U>
209       cons( const U& u )
210         : head(detail::init_head(u, 0))
211         , tail(detail::init_tail<Tail>::execute(u, 0L))
212        {
213        }
214
215       template<typename Other>
216       cons& operator=(const Other& other)
217       {
218         head = other.head;
219         tail = other.tail;
220         return *this;
221       }
222     };
223
224     namespace detail {
225
226       // Determines if the parameter is null_type
227       template<typename T> struct is_null_type { enum { RET = 0 }; };
228       template<> struct is_null_type<null_type> { enum { RET = 1 }; };
229
230       /* Build a cons structure from the given Head and Tail. If both are null_type,
231       return null_type. */
232       template<typename Head, typename Tail>
233       struct build_cons
234       {
235       private:
236         enum { tail_is_null_type = is_null_type<Tail>::RET };
237       public:
238         typedef cons<Head, Tail> RET;
239       };
240
241       template<>
242       struct build_cons<null_type, null_type>
243       {
244         typedef null_type RET;
245       };
246
247       // Map the N elements of a tuple into a cons list
248       template<
249         typename T1,
250         typename T2 = null_type,
251         typename T3 = null_type,
252         typename T4 = null_type,
253         typename T5 = null_type,
254         typename T6 = null_type,
255         typename T7 = null_type,
256         typename T8 = null_type,
257         typename T9 = null_type,
258         typename T10 = null_type
259       >
260       struct map_tuple_to_cons
261       {
262         typedef typename detail::build_cons<T10, null_type  >::RET cons10;
263         typedef typename detail::build_cons<T9, cons10>::RET cons9;
264         typedef typename detail::build_cons<T8, cons9>::RET cons8;
265         typedef typename detail::build_cons<T7, cons8>::RET cons7;
266         typedef typename detail::build_cons<T6, cons7>::RET cons6;
267         typedef typename detail::build_cons<T5, cons6>::RET cons5;
268         typedef typename detail::build_cons<T4, cons5>::RET cons4;
269         typedef typename detail::build_cons<T3, cons4>::RET cons3;
270         typedef typename detail::build_cons<T2, cons3>::RET cons2;
271         typedef typename detail::build_cons<T1, cons2>::RET cons1;
272       };
273
274       // Workaround the lack of partial specialization in some compilers
275       template<int N>
276       struct _element_type
277       {
278         template<typename Tuple>
279         struct inner
280         {
281         private:
282           typedef typename Tuple::tail_type tail_type;
283           typedef _element_type<N-1> next_elt_type;
284
285         public:
286           typedef typename _element_type<N-1>::template inner<tail_type>::RET RET;
287         };
288       };
289
290       template<>
291       struct _element_type<0>
292       {
293         template<typename Tuple>
294         struct inner
295         {
296           typedef typename Tuple::head_type RET;
297         };
298       };
299
300     } // namespace detail
301
302
303     // Return the Nth type of the given Tuple
304     template<int N, typename Tuple>
305     struct element
306     {
307     private:
308       typedef detail::_element_type<N> nth_type;
309
310     public:
311       typedef typename nth_type::template inner<Tuple>::RET RET;
312       typedef RET type;
313     };
314
315     namespace detail {
316
317 #if defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
318       // special workaround for vc7:
319
320       template <bool x>
321       struct reference_adder
322       {
323          template <class T>
324          struct rebind
325          {
326             typedef T& type;
327          };
328       };
329
330       template <>
331       struct reference_adder<true>
332       {
333          template <class T>
334          struct rebind
335          {
336             typedef T type;
337          };
338       };
339
340
341       // Return a reference to the Nth type of the given Tuple
342       template<int N, typename Tuple>
343       struct element_ref
344       {
345       private:
346          typedef typename element<N, Tuple>::RET elt_type;
347          enum { is_ref = is_reference<elt_type>::value };
348
349       public:
350          typedef reference_adder<is_ref>::rebind<elt_type>::type RET;
351          typedef RET type;
352       };
353
354       // Return a const reference to the Nth type of the given Tuple
355       template<int N, typename Tuple>
356       struct element_const_ref
357       {
358       private:
359          typedef typename element<N, Tuple>::RET elt_type;
360          enum { is_ref = is_reference<elt_type>::value };
361
362       public:
363          typedef reference_adder<is_ref>::rebind<const elt_type>::type RET;
364          typedef RET type;
365       };
366
367 #else // vc7
368
369       // Return a reference to the Nth type of the given Tuple
370       template<int N, typename Tuple>
371       struct element_ref
372       {
373       private:
374         typedef typename element<N, Tuple>::RET elt_type;
375
376       public:
377         typedef typename add_reference<elt_type>::type RET;
378         typedef RET type;
379       };
380
381       // Return a const reference to the Nth type of the given Tuple
382       template<int N, typename Tuple>
383       struct element_const_ref
384       {
385       private:
386         typedef typename element<N, Tuple>::RET elt_type;
387
388       public:
389         typedef typename add_reference<const elt_type>::type RET;
390         typedef RET type;
391       };
392 #endif // vc7
393
394     } // namespace detail
395
396     // Get length of this tuple
397     template<typename Tuple>
398     struct length
399     {
400       BOOST_STATIC_CONSTANT(int, value = 1 + length<typename Tuple::tail_type>::value);
401     };
402
403     template<> struct length<tuple<> > {
404       BOOST_STATIC_CONSTANT(int, value = 0);
405     };
406
407     template<>
408     struct length<null_type>
409     {
410       BOOST_STATIC_CONSTANT(int, value = 0);
411     };
412
413     namespace detail {
414
415     // Reference the Nth element in a tuple and retrieve it with "get"
416     template<int N>
417     struct get_class
418     {
419       template<typename Head, typename Tail>
420       static inline
421       typename detail::element_ref<N, cons<Head, Tail> >::RET
422       get(cons<Head, Tail>& t)
423       {
424         return get_class<N-1>::get(t.tail);
425       }
426
427       template<typename Head, typename Tail>
428       static inline
429       typename detail::element_const_ref<N, cons<Head, Tail> >::RET
430       get(const cons<Head, Tail>& t)
431       {
432         return get_class<N-1>::get(t.tail);
433       }
434     };
435
436     template<>
437     struct get_class<0>
438     {
439       template<typename Head, typename Tail>
440       static inline
441       typename add_reference<Head>::type
442       get(cons<Head, Tail>& t)
443       {
444         return t.head;
445       }
446
447       template<typename Head, typename Tail>
448       static inline
449       typename add_reference<const Head>::type
450       get(const cons<Head, Tail>& t)
451       {
452         return t.head;
453       }
454     };
455
456     } // namespace detail
457
458     // tuple class
459     template<
460       typename T1,
461       typename T2,
462       typename T3,
463       typename T4,
464       typename T5,
465       typename T6,
466       typename T7,
467       typename T8,
468       typename T9,
469       typename T10
470     >
471     class tuple :
472       public detail::map_tuple_to_cons<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::cons1
473     {
474     private:
475       typedef detail::map_tuple_to_cons<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> mapped_tuple;
476       typedef typename mapped_tuple::cons10 cons10;
477       typedef typename mapped_tuple::cons9 cons9;
478       typedef typename mapped_tuple::cons8 cons8;
479       typedef typename mapped_tuple::cons7 cons7;
480       typedef typename mapped_tuple::cons6 cons6;
481       typedef typename mapped_tuple::cons5 cons5;
482       typedef typename mapped_tuple::cons4 cons4;
483       typedef typename mapped_tuple::cons3 cons3;
484       typedef typename mapped_tuple::cons2 cons2;
485       typedef typename mapped_tuple::cons1 cons1;
486
487       typedef typename detail::add_const_reference<T1>::type t1_cref;
488       typedef typename detail::add_const_reference<T2>::type t2_cref;
489       typedef typename detail::add_const_reference<T3>::type t3_cref;
490       typedef typename detail::add_const_reference<T4>::type t4_cref;
491       typedef typename detail::add_const_reference<T5>::type t5_cref;
492       typedef typename detail::add_const_reference<T6>::type t6_cref;
493       typedef typename detail::add_const_reference<T7>::type t7_cref;
494       typedef typename detail::add_const_reference<T8>::type t8_cref;
495       typedef typename detail::add_const_reference<T9>::type t9_cref;
496       typedef typename detail::add_const_reference<T10>::type t10_cref;
497     public:
498       typedef cons1 inherited;
499       typedef tuple self_type;
500
501       tuple() : cons1(T1(), cons2(T2(), cons3(T3(), cons4(T4(), cons5(T5(), cons6(T6(),cons7(T7(),cons8(T8(),cons9(T9(),cons10(T10()))))))))))
502         {}
503
504       tuple(
505           t1_cref t1,
506           t2_cref t2,
507           t3_cref t3 = T3(),
508           t4_cref t4 = T4(),
509           t5_cref t5 = T5(),
510           t6_cref t6 = T6(),
511           t7_cref t7 = T7(),
512           t8_cref t8 = T8(),
513           t9_cref t9 = T9(),
514           t10_cref t10 = T10()
515       ) :
516         cons1(t1, cons2(t2, cons3(t3, cons4(t4, cons5(t5, cons6(t6,cons7(t7,cons8(t8,cons9(t9,cons10(t10))))))))))
517       {
518       }
519
520       explicit tuple(t1_cref t1)
521         : cons1(t1, cons2(T2(), cons3(T3(), cons4(T4(), cons5(T5(), cons6(T6(),cons7(T7(),cons8(T8(),cons9(T9(),cons10(T10()))))))))))
522       {}
523
524       template<typename Head, typename Tail>
525       tuple(const cons<Head, Tail>& other) :
526         cons1(other.head, other.tail)
527       {
528       }
529
530       template<typename First, typename Second>
531       self_type& operator=(const std::pair<First, Second>& other)
532       {
533         this->head = other.first;
534         this->tail.head = other.second;
535         return *this;
536       }
537
538       template<typename Head, typename Tail>
539       self_type& operator=(const cons<Head, Tail>& other)
540       {
541         this->head = other.head;
542         this->tail = other.tail;
543
544         return *this;
545       }
546     };
547
548     namespace detail {
549
550       template<int N> struct workaround_holder {};
551
552     } // namespace detail
553
554     template<int N, typename Head, typename Tail>
555     typename detail::element_ref<N, cons<Head, Tail> >::RET
556     get(cons<Head, Tail>& t, detail::workaround_holder<N>* = 0)
557     {
558       return detail::get_class<N>::get(t);
559     }
560
561     template<int N, typename Head, typename Tail>
562     typename detail::element_const_ref<N, cons<Head, Tail> >::RET
563     get(const cons<Head, Tail>& t, detail::workaround_holder<N>* = 0)
564     {
565       return detail::get_class<N>::get(t);
566     }
567
568     // Make a tuple
569     template<typename T1>
570     inline
571     tuple<T1>
572     make_tuple(const T1& t1)
573     {
574       return tuple<T1>(t1);
575     }
576
577     // Make a tuple
578     template<typename T1, typename T2>
579     inline
580     tuple<T1, T2>
581     make_tuple(const T1& t1, const T2& t2)
582     {
583       return tuple<T1, T2>(t1, t2);
584     }
585
586     // Make a tuple
587     template<typename T1, typename T2, typename T3>
588     inline
589     tuple<T1, T2, T3>
590     make_tuple(const T1& t1, const T2& t2, const T3& t3)
591     {
592       return tuple<T1, T2, T3>(t1, t2, t3);
593     }
594
595     // Make a tuple
596     template<typename T1, typename T2, typename T3, typename T4>
597     inline
598     tuple<T1, T2, T3, T4>
599     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
600     {
601       return tuple<T1, T2, T3, T4>(t1, t2, t3, t4);
602     }
603
604     // Make a tuple
605     template<typename T1, typename T2, typename T3, typename T4, typename T5>
606     inline
607     tuple<T1, T2, T3, T4, T5>
608     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
609     {
610       return tuple<T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5);
611     }
612
613     // Make a tuple
614     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
615     inline
616     tuple<T1, T2, T3, T4, T5, T6>
617     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6)
618     {
619       return tuple<T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6);
620     }
621
622     // Make a tuple
623     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
624     inline
625     tuple<T1, T2, T3, T4, T5, T6, T7>
626     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7)
627     {
628       return tuple<T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7);
629     }
630
631     // Make a tuple
632     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
633     inline
634     tuple<T1, T2, T3, T4, T5, T6, T7, T8>
635     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8)
636     {
637       return tuple<T1, T2, T3, T4, T5, T6, T7, T8>(t1, t2, t3, t4, t5, t6, t7, t8);
638     }
639
640     // Make a tuple
641     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
642     inline
643     tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>
644     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9)
645     {
646       return tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>(t1, t2, t3, t4, t5, t6, t7, t8, t9);
647     }
648
649     // Make a tuple
650     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
651     inline
652     tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>
653     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9, const T10& t10)
654     {
655       return tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
656     }
657
658     // Tie variables into a tuple
659     template<typename T1>
660     inline
661     tuple<detail::assign_to_pointee<T1> >
662     tie(T1& t1)
663     {
664       return make_tuple(detail::assign_to_pointee<T1>(&t1));
665     }
666
667     // Tie variables into a tuple
668     template<typename T1, typename T2>
669     inline
670     tuple<detail::assign_to_pointee<T1>,
671       detail::assign_to_pointee<T2> >
672     tie(T1& t1, T2& t2)
673     {
674       return make_tuple(detail::assign_to_pointee<T1>(&t1),
675                         detail::assign_to_pointee<T2>(&t2));
676     }
677
678     // Tie variables into a tuple
679     template<typename T1, typename T2, typename T3>
680     inline
681     tuple<detail::assign_to_pointee<T1>,
682       detail::assign_to_pointee<T2>,
683       detail::assign_to_pointee<T3> >
684     tie(T1& t1, T2& t2, T3& t3)
685     {
686       return make_tuple(detail::assign_to_pointee<T1>(&t1),
687                         detail::assign_to_pointee<T2>(&t2),
688                         detail::assign_to_pointee<T3>(&t3));
689     }
690
691     // Tie variables into a tuple
692     template<typename T1, typename T2, typename T3, typename T4>
693     inline
694     tuple<detail::assign_to_pointee<T1>,
695       detail::assign_to_pointee<T2>,
696       detail::assign_to_pointee<T3>,
697       detail::assign_to_pointee<T4> >
698     tie(T1& t1, T2& t2, T3& t3, T4& t4)
699     {
700       return make_tuple(detail::assign_to_pointee<T1>(&t1),
701                         detail::assign_to_pointee<T2>(&t2),
702                         detail::assign_to_pointee<T3>(&t3),
703                         detail::assign_to_pointee<T4>(&t4));
704     }
705
706     // Tie variables into a tuple
707     template<typename T1, typename T2, typename T3, typename T4, typename T5>
708     inline
709     tuple<detail::assign_to_pointee<T1>,
710       detail::assign_to_pointee<T2>,
711       detail::assign_to_pointee<T3>,
712       detail::assign_to_pointee<T4>,
713       detail::assign_to_pointee<T5> >
714     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5)
715     {
716       return make_tuple(detail::assign_to_pointee<T1>(&t1),
717                         detail::assign_to_pointee<T2>(&t2),
718                         detail::assign_to_pointee<T3>(&t3),
719                         detail::assign_to_pointee<T4>(&t4),
720                         detail::assign_to_pointee<T5>(&t5));
721     }
722
723     // Tie variables into a tuple
724     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
725     inline
726     tuple<detail::assign_to_pointee<T1>,
727       detail::assign_to_pointee<T2>,
728       detail::assign_to_pointee<T3>,
729       detail::assign_to_pointee<T4>,
730       detail::assign_to_pointee<T5>,
731       detail::assign_to_pointee<T6> >
732     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5, T6 &t6)
733     {
734       return make_tuple(detail::assign_to_pointee<T1>(&t1),
735                         detail::assign_to_pointee<T2>(&t2),
736                         detail::assign_to_pointee<T3>(&t3),
737                         detail::assign_to_pointee<T4>(&t4),
738                         detail::assign_to_pointee<T5>(&t5),
739                         detail::assign_to_pointee<T6>(&t6));
740     }
741
742     // Tie variables into a tuple
743     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
744     inline
745     tuple<detail::assign_to_pointee<T1>,
746       detail::assign_to_pointee<T2>,
747       detail::assign_to_pointee<T3>,
748       detail::assign_to_pointee<T4>,
749       detail::assign_to_pointee<T5>,
750       detail::assign_to_pointee<T6>,
751       detail::assign_to_pointee<T7> >
752     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5, T6 &t6, T7 &t7)
753     {
754       return make_tuple(detail::assign_to_pointee<T1>(&t1),
755                         detail::assign_to_pointee<T2>(&t2),
756                         detail::assign_to_pointee<T3>(&t3),
757                         detail::assign_to_pointee<T4>(&t4),
758                         detail::assign_to_pointee<T5>(&t5),
759                         detail::assign_to_pointee<T6>(&t6),
760                         detail::assign_to_pointee<T7>(&t7));
761     }
762
763     // Tie variables into a tuple
764     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
765     inline
766     tuple<detail::assign_to_pointee<T1>,
767       detail::assign_to_pointee<T2>,
768       detail::assign_to_pointee<T3>,
769       detail::assign_to_pointee<T4>,
770       detail::assign_to_pointee<T5>,
771       detail::assign_to_pointee<T6>,
772       detail::assign_to_pointee<T7>,
773       detail::assign_to_pointee<T8> >
774     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8)
775     {
776       return make_tuple(detail::assign_to_pointee<T1>(&t1),
777                         detail::assign_to_pointee<T2>(&t2),
778                         detail::assign_to_pointee<T3>(&t3),
779                         detail::assign_to_pointee<T4>(&t4),
780                         detail::assign_to_pointee<T5>(&t5),
781                         detail::assign_to_pointee<T6>(&t6),
782                         detail::assign_to_pointee<T7>(&t7),
783                         detail::assign_to_pointee<T8>(&t8));
784     }
785
786     // Tie variables into a tuple
787     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
788     inline
789     tuple<detail::assign_to_pointee<T1>,
790       detail::assign_to_pointee<T2>,
791       detail::assign_to_pointee<T3>,
792       detail::assign_to_pointee<T4>,
793       detail::assign_to_pointee<T5>,
794       detail::assign_to_pointee<T6>,
795       detail::assign_to_pointee<T7>,
796       detail::assign_to_pointee<T8>,
797       detail::assign_to_pointee<T9> >
798     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9)
799     {
800       return make_tuple(detail::assign_to_pointee<T1>(&t1),
801                         detail::assign_to_pointee<T2>(&t2),
802                         detail::assign_to_pointee<T3>(&t3),
803                         detail::assign_to_pointee<T4>(&t4),
804                         detail::assign_to_pointee<T5>(&t5),
805                         detail::assign_to_pointee<T6>(&t6),
806                         detail::assign_to_pointee<T7>(&t7),
807                         detail::assign_to_pointee<T8>(&t8),
808                         detail::assign_to_pointee<T9>(&t9));
809     }
810     // Tie variables into a tuple
811     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
812     inline
813     tuple<detail::assign_to_pointee<T1>,
814       detail::assign_to_pointee<T2>,
815       detail::assign_to_pointee<T3>,
816       detail::assign_to_pointee<T4>,
817       detail::assign_to_pointee<T5>,
818       detail::assign_to_pointee<T6>,
819       detail::assign_to_pointee<T7>,
820       detail::assign_to_pointee<T8>,
821       detail::assign_to_pointee<T9>,
822       detail::assign_to_pointee<T10> >
823     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10)
824     {
825       return make_tuple(detail::assign_to_pointee<T1>(&t1),
826                         detail::assign_to_pointee<T2>(&t2),
827                         detail::assign_to_pointee<T3>(&t3),
828                         detail::assign_to_pointee<T4>(&t4),
829                         detail::assign_to_pointee<T5>(&t5),
830                         detail::assign_to_pointee<T6>(&t6),
831                         detail::assign_to_pointee<T7>(&t7),
832                         detail::assign_to_pointee<T8>(&t8),
833                         detail::assign_to_pointee<T9>(&t9),
834                         detail::assign_to_pointee<T10>(&t10));
835     }
836     // "ignore" allows tuple positions to be ignored when using "tie".
837
838 detail::swallow_assign const ignore = detail::swallow_assign();
839
840 template <class T0, class T1, class T2, class T3, class T4,
841           class T5, class T6, class T7, class T8, class T9>
842 void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
843           tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs);
844 inline void swap(null_type&, null_type&) {}
845 template<class HH>
846 inline void swap(cons<HH, null_type>& lhs, cons<HH, null_type>& rhs) {
847   ::boost::swap(lhs.head, rhs.head);
848 }
849 template<class HH, class TT>
850 inline void swap(cons<HH, TT>& lhs, cons<HH, TT>& rhs) {
851   ::boost::swap(lhs.head, rhs.head);
852   ::boost::tuples::swap(lhs.tail, rhs.tail);
853 }
854 template <class T0, class T1, class T2, class T3, class T4,
855           class T5, class T6, class T7, class T8, class T9>
856 inline void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
857           tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs) {
858   typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
859   typedef typename tuple_type::inherited base;
860   ::boost::tuples::swap(static_cast<base&>(lhs), static_cast<base&>(rhs));
861 }
862
863 } // namespace tuples
864 } // namespace boost
865 #endif // BOOST_TUPLE_BASIC_NO_PARTIAL_SPEC_HPP