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