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