]> git.lyx.org Git - lyx.git/blob - boost/boost/tuple/detail/tuple_basic_no_partial_spec.hpp
update boost to version 1.29.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     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& operator=(const T&)
96         {
97           return *this;
98         }
99       };
100
101     template <typename T> struct add_const_reference : add_reference<typename add_const<T>::type> {};
102   } // end of namespace detail
103
104     // cons builds a heterogenous list of types
105    template<typename Head, typename Tail = null_type>
106    struct cons
107    {
108      typedef cons self_type;
109      typedef Head head_type;
110      typedef Tail tail_type;
111
112     private:
113        typedef typename boost::add_reference<head_type>::type head_ref;
114        typedef typename boost::add_reference<tail_type>::type tail_ref;
115        typedef typename detail::add_const_reference<head_type>::type head_cref;
116        typedef typename detail::add_const_reference<tail_type>::type tail_cref;
117     public:
118      head_type head;
119      tail_type tail;
120
121      head_ref get_head() { return head; }
122      tail_ref get_tail() { return tail; }  
123
124      head_cref get_head() const { return head; }
125      tail_cref get_tail() const { return tail; }
126   
127 #if defined BOOST_MSVC
128       template<typename Tail>
129       explicit cons(head_cref h /* = head_type() */, // causes MSVC 6.5 to barf.
130                     const Tail& t) : head(h), tail(t.head, t.tail)
131       {
132       }
133
134       explicit cons(head_cref h /* = head_type() */, // causes MSVC 6.5 to barf.
135                     const null_type& t) : head(h), tail(t)
136       {
137       }
138
139 #else
140       template<typename T>
141       explicit cons(head_cref h, const T& t) : 
142         head(h), tail(t.head, t.tail)
143       {
144       }
145
146       explicit cons(head_cref h = head_type(),
147                     tail_cref t = tail_type()) :
148         head(h), tail(t)
149       {
150       }
151 #endif
152
153
154       template<typename Other>
155       cons& operator=(const Other& other)
156       {
157         head = other.head;
158         tail = other.tail;
159         return *this;
160       }
161     };
162   
163     namespace detail {
164
165       // Determines if the parameter is null_type
166       template<typename T> struct is_null_type { enum { RET = 0 }; };
167       template<> struct is_null_type<null_type> { enum { RET = 1 }; };
168       
169       /* Build a cons structure from the given Head and Tail. If both are null_type,
170       return null_type. */
171       template<typename Head, typename Tail>
172       struct build_cons
173       {
174       private:
175         enum { tail_is_null_type = is_null_type<Tail>::RET };
176       public:
177         typedef cons<Head, Tail> RET;
178       };
179
180       template<>
181       struct build_cons<null_type, null_type>
182       {
183         typedef null_type RET;
184       };
185
186       // Map the N elements of a tuple into a cons list
187       template<
188         typename T1, 
189         typename T2 = null_type, 
190         typename T3 = null_type, 
191         typename T4 = null_type, 
192         typename T5 = null_type, 
193         typename T6 = null_type, 
194         typename T7 = null_type, 
195         typename T8 = null_type, 
196         typename T9 = null_type, 
197         typename T10 = null_type
198       >
199       struct map_tuple_to_cons
200       {
201         typedef typename detail::build_cons<T10, null_type  >::RET cons10;
202         typedef typename detail::build_cons<T9, cons10>::RET cons9;
203         typedef typename detail::build_cons<T8, cons9>::RET cons8;
204         typedef typename detail::build_cons<T7, cons8>::RET cons7;
205         typedef typename detail::build_cons<T6, cons7>::RET cons6;
206         typedef typename detail::build_cons<T5, cons6>::RET cons5;
207         typedef typename detail::build_cons<T4, cons5>::RET cons4;
208         typedef typename detail::build_cons<T3, cons4>::RET cons3;
209         typedef typename detail::build_cons<T2, cons3>::RET cons2;
210         typedef typename detail::build_cons<T1, cons2>::RET cons1;
211       };
212
213       // Workaround the lack of partial specialization in some compilers
214       template<int N>
215       struct _element_type
216       {
217         template<typename Tuple>
218         struct inner
219         {
220         private:
221           typedef typename Tuple::tail_type tail_type;
222           typedef _element_type<N-1> next_elt_type;
223
224         public:
225           typedef typename _element_type<N-1>::template inner<tail_type>::RET RET;
226         };
227       };
228
229       template<>
230       struct _element_type<0>
231       {
232         template<typename Tuple>
233         struct inner
234         {
235           typedef typename Tuple::head_type RET;
236         };
237       };
238
239     } // namespace detail
240
241
242     // Return the Nth type of the given Tuple
243     template<int N, typename Tuple>
244     struct element
245     {
246     private:
247       typedef detail::_element_type<N> nth_type;
248
249     public:
250       typedef typename nth_type::template inner<Tuple>::RET RET;
251       typedef RET type;
252     };
253
254     namespace detail {
255
256 #if defined(BOOST_MSVC) && (BOOST_MSVC == 1300)
257       // special workaround for vc7:
258
259       template <bool x>
260       struct reference_adder
261       {
262          template <class T>
263          struct rebind
264          {
265             typedef T& type;
266          };
267       };
268
269       template <>
270       struct reference_adder<true>
271       {
272          template <class T>
273          struct rebind
274          {
275             typedef T type;
276          };
277       };
278
279
280       // Return a reference to the Nth type of the given Tuple
281       template<int N, typename Tuple>
282       struct element_ref
283       {
284       private:
285          typedef typename element<N, Tuple>::RET elt_type;
286          enum { is_ref = is_reference<elt_type>::value };
287
288       public:
289          typedef reference_adder<is_ref>::rebind<elt_type>::type RET;
290          typedef RET type;
291       };
292
293       // Return a const reference to the Nth type of the given Tuple
294       template<int N, typename Tuple>
295       struct element_const_ref
296       {
297       private:
298          typedef typename element<N, Tuple>::RET elt_type;
299          enum { is_ref = is_reference<elt_type>::value };
300
301       public:
302          typedef reference_adder<is_ref>::rebind<const elt_type>::type RET;
303          typedef RET type;
304       };
305
306 #else // vc7
307
308       // Return a reference to the Nth type of the given Tuple
309       template<int N, typename Tuple>
310       struct element_ref
311       {
312       private:
313         typedef typename element<N, Tuple>::RET elt_type;
314
315       public:
316         typedef typename add_reference<elt_type>::type RET;
317         typedef RET type;
318       };
319
320       // Return a const reference to the Nth type of the given Tuple
321       template<int N, typename Tuple>
322       struct element_const_ref
323       {
324       private:
325         typedef typename element<N, Tuple>::RET elt_type;
326
327       public:
328         typedef typename add_reference<const elt_type>::type RET;
329         typedef RET type;
330       };
331 #endif // vc7
332
333     } // namespace detail
334
335     // Get length of this tuple
336     template<typename Tuple>
337     struct length
338     {
339       BOOST_STATIC_CONSTANT(int, value = 1 + length<typename Tuple::tail_type>::value);
340     };
341     
342     template<> struct length<tuple<> > {
343       BOOST_STATIC_CONSTANT(int, value = 0);
344     };
345
346     template<>
347     struct length<null_type>
348     {
349       BOOST_STATIC_CONSTANT(int, value = 0);
350     };
351
352     namespace detail {
353
354     // Reference the Nth element in a tuple and retrieve it with "get"
355     template<int N>
356     struct get_class
357     {
358       template<typename Head, typename Tail>
359       static inline
360       typename detail::element_ref<N, cons<Head, Tail> >::RET
361       get(cons<Head, Tail>& t)
362       {
363         return get_class<N-1>::get(t.tail);
364       }
365
366       template<typename Head, typename Tail>
367       static inline
368       typename detail::element_const_ref<N, cons<Head, Tail> >::RET
369       get(const cons<Head, Tail>& t)
370       {
371         return get_class<N-1>::get(t.tail);
372       }
373     };
374
375     template<>
376     struct get_class<0>
377     {
378       template<typename Head, typename Tail>
379       static inline
380       typename add_reference<Head>::type
381       get(cons<Head, Tail>& t)
382       {
383         return t.head;
384       }
385
386       template<typename Head, typename Tail>
387       static inline
388       typename add_reference<const Head>::type
389       get(const cons<Head, Tail>& t)
390       {
391         return t.head;
392       }
393     };
394
395     } // namespace detail
396
397     // tuple class
398     template<
399       typename T1, 
400       typename T2, 
401       typename T3, 
402       typename T4,
403       typename T5,
404       typename T6,
405       typename T7,
406       typename T8,
407       typename T9,
408       typename T10
409     >
410     class tuple : 
411       public detail::map_tuple_to_cons<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::cons1
412     {
413     private:
414       typedef detail::map_tuple_to_cons<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> mapped_tuple;
415       typedef typename mapped_tuple::cons10 cons10;
416       typedef typename mapped_tuple::cons9 cons9;
417       typedef typename mapped_tuple::cons8 cons8;
418       typedef typename mapped_tuple::cons7 cons7;
419       typedef typename mapped_tuple::cons6 cons6;
420       typedef typename mapped_tuple::cons5 cons5;
421       typedef typename mapped_tuple::cons4 cons4;
422       typedef typename mapped_tuple::cons3 cons3;
423       typedef typename mapped_tuple::cons2 cons2;
424       typedef typename mapped_tuple::cons1 cons1;
425
426       typedef typename detail::add_const_reference<T1>::type t1_cref;
427       typedef typename detail::add_const_reference<T2>::type t2_cref;
428       typedef typename detail::add_const_reference<T3>::type t3_cref;
429       typedef typename detail::add_const_reference<T4>::type t4_cref;
430       typedef typename detail::add_const_reference<T5>::type t5_cref;
431       typedef typename detail::add_const_reference<T6>::type t6_cref;
432       typedef typename detail::add_const_reference<T7>::type t7_cref;
433       typedef typename detail::add_const_reference<T8>::type t8_cref;
434       typedef typename detail::add_const_reference<T9>::type t9_cref;
435       typedef typename detail::add_const_reference<T10>::type t10_cref;
436     public:
437       typedef cons1 inherited;
438       typedef tuple self_type;
439
440       explicit tuple(t1_cref t1 = T1(), 
441                      t2_cref t2 = T2(),
442                      t3_cref t3 = T3(),
443                      t4_cref t4 = T4(),
444                      t5_cref t5 = T5(),
445                      t6_cref t6 = T6(),
446                      t7_cref t7 = T7(),
447                      t8_cref t8 = T8(),
448                      t9_cref t9 = T9(),
449                      t10_cref t10 = T10()
450           ) :
451         cons1(t1, cons2(t2, cons3(t3, cons4(t4, cons5(t5, cons6(t6,cons7(t7,cons8(t8,cons9(t9,cons10(t10))))))))))
452       {
453       }
454
455       template<typename Head, typename Tail>
456       explicit tuple(const cons<Head, Tail>& other) : 
457         cons1(other.head, other.tail)
458       {
459       }
460
461       template<typename First, typename Second>
462       self_type& operator=(const std::pair<First, Second>& other)
463       {
464         this->head = other.first;
465         this->tail.head = other.second;
466         return *this;
467       }
468
469       template<typename Head, typename Tail>
470       self_type& operator=(const cons<Head, Tail>& other)
471       {
472         this->head = other.head;
473         this->tail = other.tail;
474
475         return *this;
476       }
477     };
478
479     namespace detail {
480
481       template<int N> struct workaround_holder {};
482
483     } // namespace detail
484
485     template<int N, typename Head, typename Tail>
486     typename detail::element_ref<N, cons<Head, Tail> >::RET
487     get(cons<Head, Tail>& t, detail::workaround_holder<N>* = 0)
488     {
489       return detail::get_class<N>::get(t);
490     }
491
492     template<int N, typename Head, typename Tail>
493     typename detail::element_const_ref<N, cons<Head, Tail> >::RET
494     get(const cons<Head, Tail>& t, detail::workaround_holder<N>* = 0)
495     {
496       return detail::get_class<N>::get(t);
497     }
498
499     // Make a tuple
500     template<typename T1>
501     inline
502     tuple<T1>
503     make_tuple(const T1& t1)
504     {
505       return tuple<T1>(t1);
506     }
507
508     // Make a tuple
509     template<typename T1, typename T2>
510     inline
511     tuple<T1, T2>
512     make_tuple(const T1& t1, const T2& t2)
513     {
514       return tuple<T1, T2>(t1, t2);
515     }
516
517     // Make a tuple
518     template<typename T1, typename T2, typename T3>
519     inline
520     tuple<T1, T2, T3>
521     make_tuple(const T1& t1, const T2& t2, const T3& t3)
522     {
523       return tuple<T1, T2, T3>(t1, t2, t3);
524     }
525
526     // Make a tuple
527     template<typename T1, typename T2, typename T3, typename T4>
528     inline
529     tuple<T1, T2, T3, T4>
530     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
531     {
532       return tuple<T1, T2, T3, T4>(t1, t2, t3, t4);
533     }
534
535     // Make a tuple
536     template<typename T1, typename T2, typename T3, typename T4, typename T5>
537     inline
538     tuple<T1, T2, T3, T4, T5>
539     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
540     {
541       return tuple<T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5);
542     }
543
544     // Make a tuple
545     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
546     inline
547     tuple<T1, T2, T3, T4, T5, T6>
548     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6)
549     {
550       return tuple<T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6);
551     }
552   
553     // Make a tuple
554     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
555     inline
556     tuple<T1, T2, T3, T4, T5, T6, T7>
557     make_tuple(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7)
558     {
559       return tuple<T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7);
560     }
561
562     // Make a tuple
563     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
564     inline
565     tuple<T1, T2, T3, T4, T5, T6, T7, T8>
566     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)
567     {
568       return tuple<T1, T2, T3, T4, T5, T6, T7, T8>(t1, t2, t3, t4, t5, t6, t7, t8);
569     }
570
571     // Make a tuple
572     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
573     inline
574     tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>
575     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)
576     {
577       return tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>(t1, t2, t3, t4, t5, t6, t7, t8, t9);
578     }
579
580     // Make a tuple
581     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
582     inline
583     tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>
584     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)
585     {
586       return tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
587     }
588
589     // Tie variables into a tuple
590     template<typename T1>
591     inline
592     tuple<detail::assign_to_pointee<T1> >
593     tie(T1& t1)
594     {
595       return make_tuple(detail::assign_to_pointee<T1>(&t1));
596     }
597
598     // Tie variables into a tuple
599     template<typename T1, typename T2>
600     inline
601     tuple<detail::assign_to_pointee<T1>, 
602       detail::assign_to_pointee<T2> >
603     tie(T1& t1, T2& t2)
604     {
605       return make_tuple(detail::assign_to_pointee<T1>(&t1),
606                         detail::assign_to_pointee<T2>(&t2));
607     }
608
609     // Tie variables into a tuple
610     template<typename T1, typename T2, typename T3>
611     inline
612     tuple<detail::assign_to_pointee<T1>, 
613       detail::assign_to_pointee<T2>, 
614       detail::assign_to_pointee<T3> >
615     tie(T1& t1, T2& t2, T3& t3)
616     {
617       return make_tuple(detail::assign_to_pointee<T1>(&t1),
618                         detail::assign_to_pointee<T2>(&t2),
619                         detail::assign_to_pointee<T3>(&t3));
620     }
621
622     // Tie variables into a tuple
623     template<typename T1, typename T2, typename T3, typename T4>
624     inline
625     tuple<detail::assign_to_pointee<T1>, 
626       detail::assign_to_pointee<T2>, 
627       detail::assign_to_pointee<T3>, 
628       detail::assign_to_pointee<T4> >
629     tie(T1& t1, T2& t2, T3& t3, T4& t4)
630     {
631       return make_tuple(detail::assign_to_pointee<T1>(&t1),
632                         detail::assign_to_pointee<T2>(&t2),
633                         detail::assign_to_pointee<T3>(&t3),
634                         detail::assign_to_pointee<T4>(&t4));
635     }
636
637     // Tie variables into a tuple
638     template<typename T1, typename T2, typename T3, typename T4, typename T5>
639     inline
640     tuple<detail::assign_to_pointee<T1>, 
641       detail::assign_to_pointee<T2>, 
642       detail::assign_to_pointee<T3>, 
643       detail::assign_to_pointee<T4>, 
644       detail::assign_to_pointee<T5> >
645     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5)
646     {
647       return make_tuple(detail::assign_to_pointee<T1>(&t1),
648                         detail::assign_to_pointee<T2>(&t2),
649                         detail::assign_to_pointee<T3>(&t3),
650                         detail::assign_to_pointee<T4>(&t4),
651                         detail::assign_to_pointee<T5>(&t5));
652     }
653
654     // Tie variables into a tuple
655     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
656     inline
657     tuple<detail::assign_to_pointee<T1>, 
658       detail::assign_to_pointee<T2>, 
659       detail::assign_to_pointee<T3>, 
660       detail::assign_to_pointee<T4>, 
661       detail::assign_to_pointee<T5>, 
662       detail::assign_to_pointee<T6> >
663     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5, T6 &t6)
664     {
665       return make_tuple(detail::assign_to_pointee<T1>(&t1),
666                         detail::assign_to_pointee<T2>(&t2),
667                         detail::assign_to_pointee<T3>(&t3),
668                         detail::assign_to_pointee<T4>(&t4),
669                         detail::assign_to_pointee<T5>(&t5),
670                         detail::assign_to_pointee<T6>(&t6));
671     }
672
673     // Tie variables into a tuple
674     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
675     inline
676     tuple<detail::assign_to_pointee<T1>, 
677       detail::assign_to_pointee<T2>, 
678       detail::assign_to_pointee<T3>, 
679       detail::assign_to_pointee<T4>, 
680       detail::assign_to_pointee<T5>, 
681       detail::assign_to_pointee<T6>, 
682       detail::assign_to_pointee<T7> >
683     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5, T6 &t6, T7 &t7)
684     {
685       return make_tuple(detail::assign_to_pointee<T1>(&t1),
686                         detail::assign_to_pointee<T2>(&t2),
687                         detail::assign_to_pointee<T3>(&t3),
688                         detail::assign_to_pointee<T4>(&t4),
689                         detail::assign_to_pointee<T5>(&t5),
690                         detail::assign_to_pointee<T6>(&t6),
691                         detail::assign_to_pointee<T7>(&t7));
692     }
693
694     // Tie variables into a tuple
695     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
696     inline
697     tuple<detail::assign_to_pointee<T1>, 
698       detail::assign_to_pointee<T2>, 
699       detail::assign_to_pointee<T3>, 
700       detail::assign_to_pointee<T4>, 
701       detail::assign_to_pointee<T5>, 
702       detail::assign_to_pointee<T6>, 
703       detail::assign_to_pointee<T7>, 
704       detail::assign_to_pointee<T8> >
705     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8)
706     {
707       return make_tuple(detail::assign_to_pointee<T1>(&t1),
708                         detail::assign_to_pointee<T2>(&t2),
709                         detail::assign_to_pointee<T3>(&t3),
710                         detail::assign_to_pointee<T4>(&t4),
711                         detail::assign_to_pointee<T5>(&t5),
712                         detail::assign_to_pointee<T6>(&t6),
713                         detail::assign_to_pointee<T7>(&t7),
714                         detail::assign_to_pointee<T8>(&t8));
715     }
716
717     // Tie variables into a tuple
718     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
719     inline
720     tuple<detail::assign_to_pointee<T1>, 
721       detail::assign_to_pointee<T2>, 
722       detail::assign_to_pointee<T3>, 
723       detail::assign_to_pointee<T4>, 
724       detail::assign_to_pointee<T5>, 
725       detail::assign_to_pointee<T6>, 
726       detail::assign_to_pointee<T7>, 
727       detail::assign_to_pointee<T8>, 
728       detail::assign_to_pointee<T9> >
729     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9)
730     {
731       return make_tuple(detail::assign_to_pointee<T1>(&t1),
732                         detail::assign_to_pointee<T2>(&t2),
733                         detail::assign_to_pointee<T3>(&t3),
734                         detail::assign_to_pointee<T4>(&t4),
735                         detail::assign_to_pointee<T5>(&t5),
736                         detail::assign_to_pointee<T6>(&t6),
737                         detail::assign_to_pointee<T7>(&t7),
738                         detail::assign_to_pointee<T8>(&t8),
739                         detail::assign_to_pointee<T9>(&t9));
740     }
741     // Tie variables into a tuple
742     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
743     inline
744     tuple<detail::assign_to_pointee<T1>, 
745       detail::assign_to_pointee<T2>, 
746       detail::assign_to_pointee<T3>, 
747       detail::assign_to_pointee<T4>, 
748       detail::assign_to_pointee<T5>, 
749       detail::assign_to_pointee<T6>, 
750       detail::assign_to_pointee<T7>, 
751       detail::assign_to_pointee<T8>, 
752       detail::assign_to_pointee<T9>, 
753       detail::assign_to_pointee<T10> >
754     tie(T1& t1, T2& t2, T3& t3, T4& t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10)
755     {
756       return make_tuple(detail::assign_to_pointee<T1>(&t1),
757                         detail::assign_to_pointee<T2>(&t2),
758                         detail::assign_to_pointee<T3>(&t3),
759                         detail::assign_to_pointee<T4>(&t4),
760                         detail::assign_to_pointee<T5>(&t5),
761                         detail::assign_to_pointee<T6>(&t6),
762                         detail::assign_to_pointee<T7>(&t7),
763                         detail::assign_to_pointee<T8>(&t8),
764                         detail::assign_to_pointee<T9>(&t9),
765                         detail::assign_to_pointee<T10>(&t10));
766     }
767     // "ignore" allows tuple positions to be ignored when using "tie". 
768     namespace {
769       detail::swallow_assign ignore;
770     }
771
772 } // namespace tuples
773 } // namespace boost
774 #endif // BOOST_TUPLE_BASIC_NO_PARTIAL_SPEC_HPP