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