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