]> git.lyx.org Git - lyx.git/blob - boost/boost/tuple/detail/tuple_basic.hpp
update
[lyx.git] / boost / boost / tuple / detail / tuple_basic.hpp
1 //  tuple_basic.hpp -----------------------------------------------------
2
3 // Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
4 //
5 // Permission to copy, use, sell and distribute this software is granted
6 // provided this copyright notice appears in all copies. 
7 // Permission to modify the code and to distribute modified code is granted
8 // provided this copyright notice appears in all copies, and a notice 
9 // that the code was modified is included with the copyright notice.
10 //
11 // This software is provided "as is" without express or implied warranty, 
12 // and with no claim as to its suitability for any purpose.
13
14 // For more information, see http://www.boost.org
15
16 // Outside help:
17 // This and that, Gary Powell.
18 // Fixed return types for get_head/get_tail 
19 // ( and other bugs ) per suggestion of Jens Maurer
20 // simplified element type accessors + bug fix  (Jeremy Siek)
21 // Several changes/additions according to suggestions by Doug Gregor, 
22 // William Kempf, Vesa Karvonen, John Max Skaller, Ed Brey, Beman Davis,
23 // David Abrahams.
24
25 // Revision history:
26 // 2002 05 01 Hugo Duncan: Fix for Borland after Jaakko's previous changes
27 // 2002 04 18 Jaakko: tuple element types can be void or plain function 
28 //                    types, as long as no object is created.
29 //                    Tuple objects can no hold even noncopyable types
30 //                    such as arrays.             
31 // 2001 10 22 John Maddock
32 //      Fixes for Borland C++
33 // 2001 08 30 David Abrahams
34 //      Added default constructor for cons<>.
35 // ----------------------------------------------------------------- 
36
37 #ifndef BOOST_TUPLE_BASIC_HPP
38 #define BOOST_TUPLE_BASIC_HPP
39
40
41 #include <utility> // needed for the assignment from pair to tuple
42
43 #include "boost/type_traits/cv_traits.hpp"
44 #include "boost/type_traits/function_traits.hpp"
45     
46 namespace boost {
47 namespace tuples {
48
49 // -- null_type --------------------------------------------------------
50 struct null_type {};
51
52 // a helper function to provide a const null_type type temporary
53 namespace detail {
54   inline const null_type cnull() { return null_type(); }
55
56
57 // -- if construct ------------------------------------------------
58 // Proposed by Krzysztof Czarnecki and Ulrich Eisenecker
59
60 template <bool If, class Then, class Else> struct IF { typedef Then RET; };
61
62 template <class Then, class Else> struct IF<false, Then, Else> {
63   typedef Else RET;
64 };
65
66 } // end detail
67
68 // - cons forward declaration -----------------------------------------------
69 template <class HT, class TT> struct cons; 
70
71
72 // - tuple forward declaration -----------------------------------------------
73 template <
74   class T0 = null_type, class T1 = null_type, class T2 = null_type, 
75   class T3 = null_type, class T4 = null_type, class T5 = null_type, 
76   class T6 = null_type, class T7 = null_type, class T8 = null_type, 
77   class T9 = null_type>
78 class tuple; 
79
80 // tuple_length forward declaration
81 template<class T> struct length;
82
83
84
85 namespace detail {
86
87 #ifdef BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
88
89   template<int N> struct workaround_holder {};
90
91 #  define BOOST_TUPLE_DUMMY_PARM        , detail::workaround_holder<N>* = 0
92 #  define BOOST_TUPLE_SINGLE_DUMMY_PARM detail::workaround_holder<N>* = 0
93 #else
94 #  define BOOST_TUPLE_DUMMY_PARM
95 #  define BOOST_TUPLE_SINGLE_DUMMY_PARM
96 #endif
97
98 // -- generate error template, referencing to non-existing members of this 
99 // template is used to produce compilation errors intentionally
100 template<class T>
101 class generate_error;
102
103 // - cons getters --------------------------------------------------------
104 // called: get_class<N>::get<RETURN_TYPE>(aTuple)
105
106 template< int N >
107 struct get_class {
108   template<class RET, class HT, class TT >
109   inline static RET get(const cons<HT, TT>& t)
110   {
111     return get_class<N-1>::template get<RET>(t.tail);
112   }
113   template<class RET, class HT, class TT >
114   inline static RET get(cons<HT, TT>& t)
115   {
116     return get_class<N-1>::template get<RET>(t.tail);
117   }
118 };
119
120 template<>
121 struct get_class<0> {
122   template<class RET, class HT, class TT> 
123   inline static RET get(const cons<HT, TT>& t)
124   {
125     return t.head;
126   }
127   template<class RET, class HT, class TT> 
128   inline static RET get(cons<HT, TT>& t)
129   {
130     return t.head;
131   }
132 };
133
134 } // end of namespace detail
135
136
137 // -cons type accessors ----------------------------------------
138 // typename tuples::element<N,T>::type gets the type of the 
139 // Nth element ot T, first element is at index 0
140 // -------------------------------------------------------
141
142 template<int N, class T>
143 struct element
144 {
145 private:
146   typedef typename T::tail_type Next;
147 public:
148   typedef typename element<N-1, Next>::type type;
149 };
150 template<class T>
151 struct element<0,T>
152 {
153   typedef typename T::head_type type;
154 };
155
156 // -get function templates -----------------------------------------------
157 // Usage: get<N>(aTuple)
158
159 // -- some traits classes for get functions
160
161 // access traits lifted from detail namespace to be part of the interface,
162 // (Joel de Guzman's suggestion). Rationale: get functions are part of the
163 // interface, so should the way to express their return types be.
164
165 template <class T> struct access_traits {
166   typedef const T& const_type;
167   typedef T& non_const_type;
168
169   typedef const typename boost::remove_cv<T>::type& parameter_type;
170
171 // used as the tuple constructors parameter types
172 // Rationale: non-reference tuple element types can be cv-qualified.
173 // It should be possible to initialize such types with temporaries,
174 // and when binding temporaries to references, the reference must
175 // be non-volatile and const. 8.5.3. (5)
176 };
177
178 template <class T> struct access_traits<T&> {
179
180   typedef T& const_type;
181   typedef T& non_const_type;
182    
183   typedef T& parameter_type;   
184 };
185
186 // get function for non-const cons-lists, returns a reference to the element
187
188 template<int N, class HT, class TT>
189 inline typename access_traits<
190                   typename element<N, cons<HT, TT> >::type
191                 >::non_const_type
192 get(cons<HT, TT>& c BOOST_TUPLE_DUMMY_PARM) { 
193   return detail::get_class<N>::template 
194          get<
195            typename access_traits<
196              typename element<N, cons<HT, TT> >::type
197            >::non_const_type>(c); 
198
199
200 // get function for const cons-lists, returns a const reference to
201 // the element. If the element is a reference, returns the reference
202 // as such (that is, can return a non-const reference)
203 template<int N, class HT, class TT>
204 inline typename access_traits<
205                   typename element<N, cons<HT, TT> >::type
206                 >::const_type
207 get(const cons<HT, TT>& c BOOST_TUPLE_DUMMY_PARM) { 
208   return detail::get_class<N>::template 
209          get<
210            typename access_traits<
211              typename element<N, cons<HT, TT> >::type
212          >::const_type>(c);
213
214
215 // -- the cons template  --------------------------------------------------
216 namespace detail {
217
218 //  These helper templates wrap void types and plain function types.
219 //  The reationale is to allow one to write tuple types with those types
220 //  as elements, even though it is not possible to instantiate such object.
221 //  E.g: typedef tuple<void> some_type; // ok
222 //  but: some_type x; // fails
223
224 template <class T> class non_storeable_type {
225   non_storeable_type();
226 };
227
228 template <class T> struct wrap_non_storeable_type {
229   typedef typename IF<
230     ::boost::is_function<T>::value, non_storeable_type<T>, T
231   >::RET type;
232 };
233 template <> struct wrap_non_storeable_type<void> {
234   typedef non_storeable_type<void> type; 
235 };
236
237 } // detail
238
239 template <class HT, class TT>
240 struct cons {
241
242   typedef HT head_type;
243   typedef TT tail_type;
244
245   typedef typename 
246     detail::wrap_non_storeable_type<head_type>::type stored_head_type;
247
248   stored_head_type head;
249   tail_type tail;
250
251   typename access_traits<stored_head_type>::non_const_type 
252   get_head() { return head; }
253
254   typename access_traits<tail_type>::non_const_type 
255   get_tail() { return tail; }  
256
257   typename access_traits<stored_head_type>::const_type 
258   get_head() const { return head; }
259   
260   typename access_traits<tail_type>::const_type 
261   get_tail() const { return tail; }  
262
263   cons() : head(), tail() {}
264   //  cons() : head(detail::default_arg<HT>::f()), tail() {}
265
266   // the argument for head is not strictly needed, but it prevents 
267   // array type elements. This is good, since array type elements 
268   // cannot be supported properly in any case (no assignment, 
269   // copy works only if the tails are exactly the same type, ...)
270   
271   cons(typename access_traits<stored_head_type>::parameter_type h,
272        const tail_type& t)
273     : head (h), tail(t) {}  
274
275   template <class T1, class T2, class T3, class T4, class T5, 
276             class T6, class T7, class T8, class T9, class T10>
277   cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, 
278         T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 ) 
279     : head (t1), 
280       tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
281       {}
282
283   template <class T2, class T3, class T4, class T5, 
284             class T6, class T7, class T8, class T9, class T10>
285   cons( const null_type& t1, T2& t2, T3& t3, T4& t4, T5& t5, 
286         T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 ) 
287     : head (), 
288       tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
289       {}
290
291
292   template <class HT2, class TT2>
293   cons( const cons<HT2, TT2>& u ) : head(u.head), tail(u.tail) {}
294
295   template <class HT2, class TT2>
296   cons& operator=( const cons<HT2, TT2>& u ) { 
297     head=u.head; tail=u.tail; return *this; 
298   }
299
300   // must define assignment operator explicitly, implicit version is 
301   // illformed if HT is a reference (12.8. (12))
302   cons& operator=(const cons& u) { 
303     head = u.head; tail = u.tail;  return *this; 
304   }
305
306   template <class T1, class T2>
307   cons& operator=( const std::pair<T1, T2>& u ) { 
308     BOOST_STATIC_ASSERT(length<cons>::value == 2); // check length = 2
309     head = u.first; tail.head = u.second; return *this;
310   }
311
312   // get member functions (non-const and const)
313   template <int N>
314   typename access_traits<
315              typename element<N, cons<HT, TT> >::type
316            >::non_const_type
317   get() {
318     return boost::tuples::get<N>(*this); // delegate to non-member get
319   }
320
321   template <int N>
322   typename access_traits<
323              typename element<N, cons<HT, TT> >::type
324            >::const_type
325   get() const {
326     return boost::tuples::get<N>(*this); // delegate to non-member get
327   }
328 };
329
330 template <class HT>
331 struct cons<HT, null_type> {
332
333   typedef HT head_type;
334   typedef null_type tail_type;
335
336   typedef typename 
337     detail::wrap_non_storeable_type<head_type>::type stored_head_type;
338   stored_head_type head;
339  
340   typename access_traits<stored_head_type>::non_const_type 
341   get_head() { return head; }
342   
343   null_type get_tail() { return null_type(); }  
344
345   typename access_traits<stored_head_type>::const_type 
346   get_head() const { return head; }
347   
348   const null_type get_tail() const { return null_type(); }  
349
350   //  cons() : head(detail::default_arg<HT>::f()) {}
351   cons() : head() {}
352
353   cons(typename access_traits<stored_head_type>::parameter_type h,
354        const null_type& = null_type())
355     : head (h) {}  
356
357   template<class T1>
358   cons(T1& t1, const null_type&, const null_type&, const null_type&, 
359        const null_type&, const null_type&, const null_type&, 
360        const null_type&, const null_type&, const null_type&)
361   : head (t1) {}
362
363   cons(const null_type& t1, 
364        const null_type&, const null_type&, const null_type&, 
365        const null_type&, const null_type&, const null_type&, 
366        const null_type&, const null_type&, const null_type&)
367   : head () {}
368
369   template <class HT2>
370   cons( const cons<HT2, null_type>& u ) : head(u.head) {}
371   
372   template <class HT2>
373   cons& operator=(const cons<HT2, null_type>& u ) 
374   { head = u.head; return *this; }
375
376   // must define assignment operator explicitely, implicit version 
377   // is illformed if HT is a reference
378   cons& operator=(const cons& u) { head = u.head; return *this; }
379
380   template <int N>
381   typename access_traits<
382              typename element<N, cons>::type
383             >::non_const_type
384   get(BOOST_TUPLE_SINGLE_DUMMY_PARM) {
385     return boost::tuples::get<N>(*this);
386   }
387
388   template <int N>
389   typename access_traits<
390              typename element<N, cons>::type
391            >::const_type
392   get(BOOST_TUPLE_SINGLE_DUMMY_PARM) const {
393     return boost::tuples::get<N>(*this);
394   }
395
396 };
397
398 // templates for finding out the length of the tuple -------------------
399
400 template<class T>
401 struct length  {
402   BOOST_STATIC_CONSTANT(int, value = 1 + length<typename T::tail_type>::value);
403 };
404
405 template<>
406 struct length<tuple<> > {
407   BOOST_STATIC_CONSTANT(int, value = 0);
408 };
409
410 template<>
411 struct length<null_type> {
412   BOOST_STATIC_CONSTANT(int, value = 0);
413 };
414
415
416 namespace detail {
417
418 // Tuple to cons mapper --------------------------------------------------
419 template <class T0, class T1, class T2, class T3, class T4, 
420           class T5, class T6, class T7, class T8, class T9>
421 struct map_tuple_to_cons
422 {
423   typedef cons<T0, 
424                typename map_tuple_to_cons<T1, T2, T3, T4, T5, 
425                                           T6, T7, T8, T9, null_type>::type
426               > type;
427 };
428
429 // The empty tuple is a null_type
430 template <>
431 struct map_tuple_to_cons<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type>
432 {
433   typedef null_type type;
434 };
435
436 } // end detail
437
438 // -------------------------------------------------------------------
439 // -- tuple ------------------------------------------------------
440 template <class T0, class T1, class T2, class T3, class T4, 
441           class T5, class T6, class T7, class T8, class T9>
442
443 class tuple : 
444   public detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type   
445 {
446 public:
447   typedef typename 
448     detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type inherited;
449   typedef typename inherited::head_type head_type;
450   typedef typename inherited::tail_type tail_type;  
451
452
453 // access_traits<T>::parameter_type takes non-reference types as const T& 
454   tuple() {}
455   
456   tuple(typename access_traits<T0>::parameter_type t0)
457     : inherited(t0, detail::cnull(), detail::cnull(), detail::cnull(), 
458                 detail::cnull(), detail::cnull(), detail::cnull(), 
459                 detail::cnull(), detail::cnull(), detail::cnull()) {}
460
461   tuple(typename access_traits<T0>::parameter_type t0,
462         typename access_traits<T1>::parameter_type t1)
463     : inherited(t0, t1, detail::cnull(), detail::cnull(), 
464                 detail::cnull(), detail::cnull(), detail::cnull(), 
465                 detail::cnull(), detail::cnull(), detail::cnull()) {}
466
467   tuple(typename access_traits<T0>::parameter_type t0,
468         typename access_traits<T1>::parameter_type t1,
469         typename access_traits<T2>::parameter_type t2)
470     : inherited(t0, t1, t2, detail::cnull(), detail::cnull(), 
471                 detail::cnull(), detail::cnull(), detail::cnull(), 
472                 detail::cnull(), detail::cnull()) {}
473
474   tuple(typename access_traits<T0>::parameter_type t0,
475         typename access_traits<T1>::parameter_type t1,
476         typename access_traits<T2>::parameter_type t2,
477         typename access_traits<T3>::parameter_type t3)
478     : inherited(t0, t1, t2, t3, detail::cnull(), detail::cnull(), 
479                 detail::cnull(), detail::cnull(), detail::cnull(), 
480                 detail::cnull()) {}
481
482   tuple(typename access_traits<T0>::parameter_type t0,
483         typename access_traits<T1>::parameter_type t1,
484         typename access_traits<T2>::parameter_type t2,
485         typename access_traits<T3>::parameter_type t3,
486         typename access_traits<T4>::parameter_type t4)
487     : inherited(t0, t1, t2, t3, t4, detail::cnull(), detail::cnull(), 
488                 detail::cnull(), detail::cnull(), detail::cnull()) {}
489
490   tuple(typename access_traits<T0>::parameter_type t0,
491         typename access_traits<T1>::parameter_type t1,
492         typename access_traits<T2>::parameter_type t2,
493         typename access_traits<T3>::parameter_type t3,
494         typename access_traits<T4>::parameter_type t4,
495         typename access_traits<T5>::parameter_type t5)
496     : inherited(t0, t1, t2, t3, t4, t5, detail::cnull(), detail::cnull(), 
497                 detail::cnull(), detail::cnull()) {}
498
499   tuple(typename access_traits<T0>::parameter_type t0,
500         typename access_traits<T1>::parameter_type t1,
501         typename access_traits<T2>::parameter_type t2,
502         typename access_traits<T3>::parameter_type t3,
503         typename access_traits<T4>::parameter_type t4,
504         typename access_traits<T5>::parameter_type t5,
505         typename access_traits<T6>::parameter_type t6)
506     : inherited(t0, t1, t2, t3, t4, t5, t6, detail::cnull(), 
507                 detail::cnull(), detail::cnull()) {}
508
509   tuple(typename access_traits<T0>::parameter_type t0,
510         typename access_traits<T1>::parameter_type t1,
511         typename access_traits<T2>::parameter_type t2,
512         typename access_traits<T3>::parameter_type t3,
513         typename access_traits<T4>::parameter_type t4,
514         typename access_traits<T5>::parameter_type t5,
515         typename access_traits<T6>::parameter_type t6,
516         typename access_traits<T7>::parameter_type t7)
517     : inherited(t0, t1, t2, t3, t4, t5, t6, t7, detail::cnull(), 
518                 detail::cnull()) {}
519
520   tuple(typename access_traits<T0>::parameter_type t0,
521         typename access_traits<T1>::parameter_type t1,
522         typename access_traits<T2>::parameter_type t2,
523         typename access_traits<T3>::parameter_type t3,
524         typename access_traits<T4>::parameter_type t4,
525         typename access_traits<T5>::parameter_type t5,
526         typename access_traits<T6>::parameter_type t6,
527         typename access_traits<T7>::parameter_type t7,
528         typename access_traits<T8>::parameter_type t8)
529     : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, detail::cnull()) {}
530
531   tuple(typename access_traits<T0>::parameter_type t0,
532         typename access_traits<T1>::parameter_type t1,
533         typename access_traits<T2>::parameter_type t2,
534         typename access_traits<T3>::parameter_type t3,
535         typename access_traits<T4>::parameter_type t4,
536         typename access_traits<T5>::parameter_type t5,
537         typename access_traits<T6>::parameter_type t6,
538         typename access_traits<T7>::parameter_type t7,
539         typename access_traits<T8>::parameter_type t8,
540         typename access_traits<T9>::parameter_type t9)
541     : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {}
542
543
544   template<class U1, class U2>
545   tuple(const cons<U1, U2>& p) : inherited(p) {}
546
547   template <class U1, class U2>
548   tuple& operator=(const cons<U1, U2>& k) { 
549     inherited::operator=(k); 
550     return *this;
551   }
552
553   template <class U1, class U2>
554   tuple& operator=(const std::pair<U1, U2>& k) { 
555     BOOST_STATIC_ASSERT(length<tuple>::value == 2);// check_length = 2
556     this->head = k.first;
557     this->tail.head = k.second; 
558     return *this;
559   }
560
561 };
562
563 // The empty tuple
564 template <>
565 class tuple<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type>  : 
566   public null_type 
567 {
568 public:
569   typedef null_type inherited;
570 };
571
572
573 // Swallows any assignment   (by Doug Gregor)
574 namespace detail {
575
576 struct swallow_assign {
577       
578   template<typename T>
579   swallow_assign& operator=(const T&) {
580     return *this;
581   }
582 };
583
584 } // namespace detail
585
586 // "ignore" allows tuple positions to be ignored when using "tie". 
587 namespace {
588  detail::swallow_assign ignore;
589 }
590
591 // ---------------------------------------------------------------------------
592 // The call_traits for make_tuple
593 // Honours the reference_wrapper class.
594
595 // Must be instantiated with plain or const plain types (not with references)
596
597 // from template<class T> foo(const T& t) : make_tuple_traits<const T>::type
598 // from template<class T> foo(T& t) : make_tuple_traits<T>::type
599
600 // Conversions:
601 // T -> T, 
602 // references -> compile_time_error
603 // reference_wrapper<T> -> T&
604 // const reference_wrapper<T> -> T&
605 // array -> const ref array
606
607
608 template<class T>
609 struct make_tuple_traits {
610   typedef T type; 
611
612   // commented away, see below  (JJ)
613   //  typedef typename IF<                 
614   //  boost::is_function<T>::value,
615   //  T&,
616   //  T>::RET type;
617
618 };
619  
620 // The is_function test was there originally for plain function types, 
621 // which can't be stored as such (we must either store them as references or
622 // pointers). Such a type could be formed if make_tuple was called with a 
623 // reference to a function.
624 // But this would mean that a const qualified function type was formed in
625 // the make_tuple function and hence make_tuple can't take a function
626 // reference as a parameter, and thus T can't be a function type.
627 // So is_function test was removed.
628 // (14.8.3. says that type deduction fails if a cv-qualified function type
629 // is created. (It only applies for the case of explicitly specifying template
630 // args, though?)) (JJ)
631
632 template<class T>
633 struct make_tuple_traits<T&> {
634   typedef typename
635      detail::generate_error<T&>::
636        do_not_use_with_reference_type error;
637 }; 
638
639 // Arrays can't be stored as plain types; convert them to references.
640 // All arrays are converted to const. This is because make_tuple takes its
641 // parameters as const T& and thus the knowledge of the potential 
642 // non-constness of actual argument is lost.
643 template<class T, int n>  struct make_tuple_traits <T[n]> {
644   typedef const T (&type)[n];
645 };
646
647 template<class T, int n> 
648 struct make_tuple_traits<const T[n]> {
649   typedef const T (&type)[n];
650 };
651
652 template<class T, int n>  struct make_tuple_traits<volatile T[n]> {
653   typedef const volatile T (&type)[n];
654 };
655
656 template<class T, int n> 
657 struct make_tuple_traits<const volatile T[n]> {
658   typedef const volatile T (&type)[n];
659 };
660
661 template<class T> 
662 struct make_tuple_traits<reference_wrapper<T> >{
663   typedef T& type;
664 };
665
666 template<class T> 
667 struct make_tuple_traits<const reference_wrapper<T> >{
668   typedef T& type;
669 };
670
671
672
673
674 namespace detail {
675
676 // a helper traits to make the make_tuple functions shorter (Vesa Karvonen's
677 // suggestion)
678 template <
679   class T0 = null_type, class T1 = null_type, class T2 = null_type, 
680   class T3 = null_type, class T4 = null_type, class T5 = null_type, 
681   class T6 = null_type, class T7 = null_type, class T8 = null_type, 
682   class T9 = null_type
683 >
684 struct make_tuple_mapper {
685   typedef
686     tuple<typename make_tuple_traits<T0>::type, 
687           typename make_tuple_traits<T1>::type, 
688           typename make_tuple_traits<T2>::type, 
689           typename make_tuple_traits<T3>::type, 
690           typename make_tuple_traits<T4>::type, 
691           typename make_tuple_traits<T5>::type, 
692           typename make_tuple_traits<T6>::type, 
693           typename make_tuple_traits<T7>::type,
694           typename make_tuple_traits<T8>::type,
695           typename make_tuple_traits<T9>::type> type;
696 };
697
698 } // end detail
699
700 // -make_tuple function templates -----------------------------------
701 inline tuple<> make_tuple() {
702   return tuple<>(); 
703 }
704
705 template<class T0>
706 inline typename detail::make_tuple_mapper<T0>::type
707 make_tuple(const T0& t0) {
708   typedef typename detail::make_tuple_mapper<T0>::type t;
709   return t(t0);
710 }
711
712 template<class T0, class T1>
713 inline typename detail::make_tuple_mapper<T0, T1>::type
714 make_tuple(const T0& t0, const T1& t1) {
715   typedef typename detail::make_tuple_mapper<T0, T1>::type t;
716   return t(t0, t1);
717 }
718
719 template<class T0, class T1, class T2>
720 inline typename detail::make_tuple_mapper<T0, T1, T2>::type
721 make_tuple(const T0& t0, const T1& t1, const T2& t2) {
722   typedef typename detail::make_tuple_mapper<T0, T1, T2>::type t;
723   return t(t0, t1, t2);
724 }
725
726 template<class T0, class T1, class T2, class T3>
727 inline typename detail::make_tuple_mapper<T0, T1, T2, T3>::type
728 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3) {
729   typedef typename detail::make_tuple_mapper<T0, T1, T2, T3>::type t;
730   return t(t0, t1, t2, t3);
731 }
732
733 template<class T0, class T1, class T2, class T3, class T4>
734 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type
735 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
736                   const T4& t4) {
737   typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type t;
738   return t(t0, t1, t2, t3, t4); 
739 }
740
741 template<class T0, class T1, class T2, class T3, class T4, class T5>
742 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type
743 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
744                   const T4& t4, const T5& t5) {
745   typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type t;
746   return t(t0, t1, t2, t3, t4, t5); 
747 }
748
749 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
750 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6>::type
751 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
752                   const T4& t4, const T5& t5, const T6& t6) {
753   typedef typename detail::make_tuple_mapper
754            <T0, T1, T2, T3, T4, T5, T6>::type t;
755   return t(t0, t1, t2, t3, t4, t5, t6);
756 }
757
758 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
759          class T7>
760 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
761 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
762                   const T4& t4, const T5& t5, const T6& t6, const T7& t7) {
763   typedef typename detail::make_tuple_mapper
764            <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
765   return t(t0, t1, t2, t3, t4, t5, t6, t7); 
766 }
767
768 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
769          class T7, class T8>
770 inline typename detail::make_tuple_mapper
771   <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
772 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
773                   const T4& t4, const T5& t5, const T6& t6, const T7& t7,
774                   const T8& t8) {
775   typedef typename detail::make_tuple_mapper
776            <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
777   return t(t0, t1, t2, t3, t4, t5, t6, t7, t8); 
778 }
779
780 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
781          class T7, class T8, class T9>
782 inline typename detail::make_tuple_mapper
783   <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
784 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
785                   const T4& t4, const T5& t5, const T6& t6, const T7& t7,
786                   const T8& t8, const T9& t9) {
787   typedef typename detail::make_tuple_mapper
788            <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
789   return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9); 
790 }
791
792
793
794 // Tie function templates -------------------------------------------------
795 template<class T1>
796 inline tuple<T1&> tie(T1& t1) {
797   return tuple<T1&> (t1);
798 }
799
800 template<class T1, class T2>
801 inline tuple<T1&, T2&> tie(T1& t1, T2& t2) {
802   return tuple<T1&, T2&> (t1, t2);
803 }
804
805 template<class T1, class T2, class T3>
806 inline tuple<T1&, T2&, T3&> tie(T1& t1, T2& t2, T3& t3) {
807   return tuple<T1&, T2&, T3&> (t1, t2, t3);
808 }
809
810 template<class T1, class T2, class T3, class T4>
811 inline tuple<T1&, T2&, T3&, T4&> tie(T1& t1, T2& t2, T3& t3, T4& t4) {
812   return tuple<T1&, T2&, T3&, T4&> (t1, t2, t3, t4);
813 }
814
815 template<class T1, class T2, class T3, class T4, class T5>
816 inline tuple<T1&, T2&, T3&, T4&, T5&> 
817 tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) {
818   return tuple<T1&, T2&, T3&, T4&, T5&> (t1, t2, t3, t4, t5);
819 }
820
821 template<class T1, class T2, class T3, class T4, class T5, class T6>
822 inline tuple<T1&, T2&, T3&, T4&, T5&, T6&> 
823 tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6) {
824   return tuple<T1&, T2&, T3&, T4&, T5&, T6&> (t1, t2, t3, t4, t5, t6);
825 }
826
827 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
828 inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&> 
829 tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7) {
830   return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&> (t1, t2, t3, t4, t5, t6, t7);
831 }
832
833 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, 
834          class T8>
835 inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&> 
836 tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8) {
837   return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&> 
838            (t1, t2, t3, t4, t5, t6, t7, t8);
839 }
840
841 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, 
842          class T8, class T9>
843 inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&> 
844 tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, 
845            T9& t9) {
846   return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&> 
847             (t1, t2, t3, t4, t5, t6, t7, t8, t9);
848 }
849
850 template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, 
851          class T8, class T9, class T10>
852 inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&, T10&> 
853 tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, 
854            T9& t9, T10& t10) {
855   return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&, T10&> 
856            (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
857 }
858
859 } // end of namespace tuples
860 } // end of namespace boost
861
862 #undef BOOST_TUPLE_DUMMY_PARM
863 #undef BOOST_TUPLE_SINGLE_DUMMY_PARM
864
865 #endif // BOOST_TUPLE_BASIC_HPP
866
867