Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:55

0001 //  tuple_basic.hpp -----------------------------------------------------
0002 
0003 // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See
0006 // accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 // For more information, see http://www.boost.org
0010 
0011 // Outside help:
0012 // This and that, Gary Powell.
0013 // Fixed return types for get_head/get_tail
0014 // ( and other bugs ) per suggestion of Jens Maurer
0015 // simplified element type accessors + bug fix  (Jeremy Siek)
0016 // Several changes/additions according to suggestions by Douglas Gregor,
0017 // William Kempf, Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes,
0018 // David Abrahams.
0019 
0020 // Revision history:
0021 // 2002 05 01 Hugo Duncan: Fix for Borland after Jaakko's previous changes
0022 // 2002 04 18 Jaakko: tuple element types can be void or plain function
0023 //                    types, as long as no object is created.
0024 //                    Tuple objects can no hold even noncopyable types
0025 //                    such as arrays.
0026 // 2001 10 22 John Maddock
0027 //      Fixes for Borland C++
0028 // 2001 08 30 David Abrahams
0029 //      Added default constructor for cons<>.
0030 // -----------------------------------------------------------------
0031 
0032 #ifndef BOOST_TUPLE_BASIC_HPP
0033 #define BOOST_TUPLE_BASIC_HPP
0034 
0035 
0036 #include <utility> // needed for the assignment from pair to tuple
0037 #include <cstddef> // for std::size_t
0038 
0039 #include <boost/core/invoke_swap.hpp>
0040 #include <boost/type_traits/cv_traits.hpp>
0041 #include <boost/type_traits/function_traits.hpp>
0042 #include <boost/type_traits/integral_constant.hpp>
0043 
0044 #include <boost/detail/workaround.hpp> // needed for BOOST_WORKAROUND
0045 
0046 #if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
0047 #pragma GCC diagnostic push
0048 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
0049 #endif
0050 
0051 namespace boost {
0052 namespace tuples {
0053 
0054 // -- null_type --------------------------------------------------------
0055 struct null_type {};
0056 
0057 // a helper function to provide a const null_type type temporary
0058 namespace detail {
0059   inline const null_type cnull() { return null_type(); }
0060 
0061 
0062 // -- if construct ------------------------------------------------
0063 // Proposed by Krzysztof Czarnecki and Ulrich Eisenecker
0064 
0065 template <bool If, class Then, class Else> struct IF { typedef Then RET; };
0066 
0067 template <class Then, class Else> struct IF<false, Then, Else> {
0068   typedef Else RET;
0069 };
0070 
0071 } // end detail
0072 
0073 // - cons forward declaration -----------------------------------------------
0074 template <class HT, class TT> struct cons;
0075 
0076 
0077 // - tuple forward declaration -----------------------------------------------
0078 template <
0079   class T0 = null_type, class T1 = null_type, class T2 = null_type,
0080   class T3 = null_type, class T4 = null_type, class T5 = null_type,
0081   class T6 = null_type, class T7 = null_type, class T8 = null_type,
0082   class T9 = null_type>
0083 class tuple;
0084 
0085 // tuple_length forward declaration
0086 template<class T> struct length;
0087 
0088 
0089 
0090 namespace detail {
0091 
0092 // -- generate error template, referencing to non-existing members of this
0093 // template is used to produce compilation errors intentionally
0094 template<class T>
0095 class generate_error;
0096 
0097 template<std::size_t N>
0098 struct drop_front {
0099     template<class Tuple>
0100     struct apply {
0101         typedef BOOST_DEDUCED_TYPENAME drop_front<N-1>::BOOST_NESTED_TEMPLATE
0102             apply<Tuple> next;
0103         typedef BOOST_DEDUCED_TYPENAME next::type::tail_type type;
0104         static const type& call(const Tuple& tup) {
0105             return next::call(tup).tail;
0106         }
0107     };
0108 };
0109 
0110 template<>
0111 struct drop_front<0> {
0112     template<class Tuple>
0113     struct apply {
0114         typedef Tuple type;
0115         static const type& call(const Tuple& tup) {
0116             return tup;
0117         }
0118     };
0119 };
0120 
0121 } // end of namespace detail
0122 
0123 
0124 // -cons type accessors ----------------------------------------
0125 // typename tuples::element<N,T>::type gets the type of the
0126 // Nth element ot T, first element is at index 0
0127 // -------------------------------------------------------
0128 
0129 #ifndef BOOST_NO_CV_SPECIALIZATIONS
0130 
0131 template<std::size_t N, class T>
0132 struct element
0133 {
0134   typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
0135       apply<T>::type::head_type type;
0136 };
0137 
0138 template<std::size_t N, class T>
0139 struct element<N, const T>
0140 {
0141 private:
0142   typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
0143       apply<T>::type::head_type unqualified_type;
0144 public:
0145 #if BOOST_WORKAROUND(BOOST_BORLANDC,<0x600)
0146   typedef const unqualified_type type;
0147 #else
0148   typedef BOOST_DEDUCED_TYPENAME boost::add_const<unqualified_type>::type type;
0149 #endif
0150 };
0151 #else // def BOOST_NO_CV_SPECIALIZATIONS
0152 
0153 namespace detail {
0154 
0155 template<std::size_t N, class T, bool IsConst>
0156 struct element_impl
0157 {
0158   typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
0159       apply<T>::type::head_type type;
0160 };
0161 
0162 template<std::size_t N, class T>
0163 struct element_impl<N, T, true /* IsConst */>
0164 {
0165   typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
0166       apply<T>::type::head_type unqualified_type;
0167   typedef const unqualified_type type;
0168 };
0169 
0170 } // end of namespace detail
0171 
0172 
0173 template<std::size_t N, class T>
0174 struct element:
0175   public detail::element_impl<N, T, ::boost::is_const<T>::value>
0176 {
0177 };
0178 
0179 #endif
0180 
0181 
0182 // -get function templates -----------------------------------------------
0183 // Usage: get<N>(aTuple)
0184 
0185 // -- some traits classes for get functions
0186 
0187 // access traits lifted from detail namespace to be part of the interface,
0188 // (Joel de Guzman's suggestion). Rationale: get functions are part of the
0189 // interface, so should the way to express their return types be.
0190 
0191 template <class T> struct access_traits {
0192   typedef const T& const_type;
0193   typedef T& non_const_type;
0194 
0195   typedef const typename boost::remove_cv<T>::type& parameter_type;
0196 
0197 // used as the tuple constructors parameter types
0198 // Rationale: non-reference tuple element types can be cv-qualified.
0199 // It should be possible to initialize such types with temporaries,
0200 // and when binding temporaries to references, the reference must
0201 // be non-volatile and const. 8.5.3. (5)
0202 };
0203 
0204 template <class T> struct access_traits<T&> {
0205 
0206   typedef T& const_type;
0207   typedef T& non_const_type;
0208 
0209   typedef T& parameter_type;
0210 };
0211 
0212 // get function for non-const cons-lists, returns a reference to the element
0213 
0214 template<std::size_t N, class HT, class TT>
0215 inline typename access_traits<
0216                   typename element<N, cons<HT, TT> >::type
0217                 >::non_const_type
0218 get(cons<HT, TT>& c) {
0219   typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
0220       apply<cons<HT, TT> > impl;
0221   typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
0222   return const_cast<cons_element&>(impl::call(c)).head;
0223 }
0224 
0225 // get function for const cons-lists, returns a const reference to
0226 // the element. If the element is a reference, returns the reference
0227 // as such (that is, can return a non-const reference)
0228 template<std::size_t N, class HT, class TT>
0229 inline typename access_traits<
0230                   typename element<N, cons<HT, TT> >::type
0231                 >::const_type
0232 get(const cons<HT, TT>& c) {
0233   typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
0234       apply<cons<HT, TT> > impl;
0235   return impl::call(c).head;
0236 }
0237 
0238 // -- the cons template  --------------------------------------------------
0239 namespace detail {
0240 
0241 //  These helper templates wrap void types and plain function types.
0242 //  The reationale is to allow one to write tuple types with those types
0243 //  as elements, even though it is not possible to instantiate such object.
0244 //  E.g: typedef tuple<void> some_type; // ok
0245 //  but: some_type x; // fails
0246 
0247 template <class T> class non_storeable_type {
0248   non_storeable_type();
0249 };
0250 
0251 template <class T> struct wrap_non_storeable_type {
0252   typedef typename IF<
0253     ::boost::is_function<T>::value, non_storeable_type<T>, T
0254   >::RET type;
0255 };
0256 template <> struct wrap_non_storeable_type<void> {
0257   typedef non_storeable_type<void> type;
0258 };
0259 
0260 } // detail
0261 
0262 template <class HT, class TT>
0263 struct cons {
0264 
0265   typedef HT head_type;
0266   typedef TT tail_type;
0267 
0268   typedef typename
0269     detail::wrap_non_storeable_type<head_type>::type stored_head_type;
0270 
0271   stored_head_type head;
0272   tail_type tail;
0273 
0274   typename access_traits<stored_head_type>::non_const_type
0275   get_head() { return head; }
0276 
0277   typename access_traits<tail_type>::non_const_type
0278   get_tail() { return tail; }
0279 
0280   typename access_traits<stored_head_type>::const_type
0281   get_head() const { return head; }
0282 
0283   typename access_traits<tail_type>::const_type
0284   get_tail() const { return tail; }
0285 
0286   cons() : head(), tail() {}
0287   //  cons() : head(detail::default_arg<HT>::f()), tail() {}
0288 
0289   // the argument for head is not strictly needed, but it prevents
0290   // array type elements. This is good, since array type elements
0291   // cannot be supported properly in any case (no assignment,
0292   // copy works only if the tails are exactly the same type, ...)
0293 
0294   cons(typename access_traits<stored_head_type>::parameter_type h,
0295        const tail_type& t)
0296     : head (h), tail(t) {}
0297 
0298   template <class T1, class T2, class T3, class T4, class T5,
0299             class T6, class T7, class T8, class T9, class T10>
0300   cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
0301         T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
0302     : head (t1),
0303       tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
0304       {}
0305 
0306   template <class T2, class T3, class T4, class T5,
0307             class T6, class T7, class T8, class T9, class T10>
0308   cons( const null_type& /*t1*/, T2& t2, T3& t3, T4& t4, T5& t5,
0309         T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
0310     : head (),
0311       tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
0312       {}
0313 
0314   cons( const cons& u ) : head(u.head), tail(u.tail) {}
0315 
0316   template <class HT2, class TT2>
0317   cons( const cons<HT2, TT2>& u ) : head(u.head), tail(u.tail) {}
0318 
0319   template <class HT2, class TT2>
0320   cons& operator=( const cons<HT2, TT2>& u ) {
0321     head=u.head; tail=u.tail; return *this;
0322   }
0323 
0324   // must define assignment operator explicitly, implicit version is
0325   // illformed if HT is a reference (12.8. (12))
0326   cons& operator=(const cons& u) {
0327     head = u.head; tail = u.tail;  return *this;
0328   }
0329 
0330   template <class T1, class T2>
0331   cons& operator=( const std::pair<T1, T2>& u ) {
0332     BOOST_STATIC_ASSERT(length<cons>::value == 2); // check length = 2
0333     head = u.first; tail.head = u.second; return *this;
0334   }
0335 
0336   // get member functions (non-const and const)
0337   template <std::size_t N>
0338   typename access_traits<
0339              typename element<N, cons<HT, TT> >::type
0340            >::non_const_type
0341   get() {
0342     return boost::tuples::get<N>(*this); // delegate to non-member get
0343   }
0344 
0345   template <std::size_t N>
0346   typename access_traits<
0347              typename element<N, cons<HT, TT> >::type
0348            >::const_type
0349   get() const {
0350     return boost::tuples::get<N>(*this); // delegate to non-member get
0351   }
0352 };
0353 
0354 template <class HT>
0355 struct cons<HT, null_type> {
0356 
0357   typedef HT head_type;
0358   typedef null_type tail_type;
0359   typedef cons<HT, null_type> self_type;
0360 
0361   typedef typename
0362     detail::wrap_non_storeable_type<head_type>::type stored_head_type;
0363   stored_head_type head;
0364 
0365   typename access_traits<stored_head_type>::non_const_type
0366   get_head() { return head; }
0367 
0368   null_type get_tail() { return null_type(); }
0369 
0370   typename access_traits<stored_head_type>::const_type
0371   get_head() const { return head; }
0372 
0373   const null_type get_tail() const { return null_type(); }
0374 
0375   //  cons() : head(detail::default_arg<HT>::f()) {}
0376   cons() : head() {}
0377 
0378   cons(typename access_traits<stored_head_type>::parameter_type h,
0379        const null_type& = null_type())
0380     : head (h) {}
0381 
0382   template<class T1>
0383   cons(T1& t1, const null_type&, const null_type&, const null_type&,
0384        const null_type&, const null_type&, const null_type&,
0385        const null_type&, const null_type&, const null_type&)
0386   : head (t1) {}
0387 
0388   cons(const null_type&,
0389        const null_type&, const null_type&, const null_type&,
0390        const null_type&, const null_type&, const null_type&,
0391        const null_type&, const null_type&, const null_type&)
0392   : head () {}
0393 
0394   cons( const cons& u ) : head(u.head) {}
0395 
0396   template <class HT2>
0397   cons( const cons<HT2, null_type>& u ) : head(u.head) {}
0398 
0399   template <class HT2>
0400   cons& operator=(const cons<HT2, null_type>& u )
0401   { head = u.head; return *this; }
0402 
0403   // must define assignment operator explicitely, implicit version
0404   // is illformed if HT is a reference
0405   cons& operator=(const cons& u) { head = u.head; return *this; }
0406 
0407   template <std::size_t N>
0408   typename access_traits<
0409              typename element<N, self_type>::type
0410             >::non_const_type
0411   get() {
0412     return boost::tuples::get<N>(*this);
0413   }
0414 
0415   template <std::size_t N>
0416   typename access_traits<
0417              typename element<N, self_type>::type
0418            >::const_type
0419   get() const {
0420     return boost::tuples::get<N>(*this);
0421   }
0422 
0423 };
0424 
0425 // templates for finding out the length of the tuple -------------------
0426 
0427 template<class T>
0428 struct length: boost::integral_constant<std::size_t, 1 + length<typename T::tail_type>::value>
0429 {
0430 };
0431 
0432 template<>
0433 struct length<tuple<> >: boost::integral_constant<std::size_t, 0>
0434 {
0435 };
0436 
0437 template<>
0438 struct length<tuple<> const>: boost::integral_constant<std::size_t, 0>
0439 {
0440 };
0441 
0442 template<>
0443 struct length<null_type>: boost::integral_constant<std::size_t, 0>
0444 {
0445 };
0446 
0447 template<>
0448 struct length<null_type const>: boost::integral_constant<std::size_t, 0>
0449 {
0450 };
0451 
0452 namespace detail {
0453 
0454 // Tuple to cons mapper --------------------------------------------------
0455 template <class T0, class T1, class T2, class T3, class T4,
0456           class T5, class T6, class T7, class T8, class T9>
0457 struct map_tuple_to_cons
0458 {
0459   typedef cons<T0,
0460                typename map_tuple_to_cons<T1, T2, T3, T4, T5,
0461                                           T6, T7, T8, T9, null_type>::type
0462               > type;
0463 };
0464 
0465 // The empty tuple is a null_type
0466 template <>
0467 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>
0468 {
0469   typedef null_type type;
0470 };
0471 
0472 } // end detail
0473 
0474 // -------------------------------------------------------------------
0475 // -- tuple ------------------------------------------------------
0476 template <class T0, class T1, class T2, class T3, class T4,
0477           class T5, class T6, class T7, class T8, class T9>
0478 
0479 class tuple :
0480   public detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
0481 {
0482 public:
0483   typedef typename
0484     detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type inherited;
0485   typedef typename inherited::head_type head_type;
0486   typedef typename inherited::tail_type tail_type;
0487 
0488 
0489 // access_traits<T>::parameter_type takes non-reference types as const T&
0490   tuple() {}
0491 
0492   explicit tuple(typename access_traits<T0>::parameter_type t0)
0493     : inherited(t0, detail::cnull(), detail::cnull(), detail::cnull(),
0494                 detail::cnull(), detail::cnull(), detail::cnull(),
0495                 detail::cnull(), detail::cnull(), detail::cnull()) {}
0496 
0497   tuple(typename access_traits<T0>::parameter_type t0,
0498         typename access_traits<T1>::parameter_type t1)
0499     : inherited(t0, t1, detail::cnull(), detail::cnull(),
0500                 detail::cnull(), detail::cnull(), detail::cnull(),
0501                 detail::cnull(), detail::cnull(), detail::cnull()) {}
0502 
0503   tuple(typename access_traits<T0>::parameter_type t0,
0504         typename access_traits<T1>::parameter_type t1,
0505         typename access_traits<T2>::parameter_type t2)
0506     : inherited(t0, t1, t2, detail::cnull(), detail::cnull(),
0507                 detail::cnull(), detail::cnull(), detail::cnull(),
0508                 detail::cnull(), detail::cnull()) {}
0509 
0510   tuple(typename access_traits<T0>::parameter_type t0,
0511         typename access_traits<T1>::parameter_type t1,
0512         typename access_traits<T2>::parameter_type t2,
0513         typename access_traits<T3>::parameter_type t3)
0514     : inherited(t0, t1, t2, t3, detail::cnull(), detail::cnull(),
0515                 detail::cnull(), detail::cnull(), detail::cnull(),
0516                 detail::cnull()) {}
0517 
0518   tuple(typename access_traits<T0>::parameter_type t0,
0519         typename access_traits<T1>::parameter_type t1,
0520         typename access_traits<T2>::parameter_type t2,
0521         typename access_traits<T3>::parameter_type t3,
0522         typename access_traits<T4>::parameter_type t4)
0523     : inherited(t0, t1, t2, t3, t4, detail::cnull(), detail::cnull(),
0524                 detail::cnull(), detail::cnull(), detail::cnull()) {}
0525 
0526   tuple(typename access_traits<T0>::parameter_type t0,
0527         typename access_traits<T1>::parameter_type t1,
0528         typename access_traits<T2>::parameter_type t2,
0529         typename access_traits<T3>::parameter_type t3,
0530         typename access_traits<T4>::parameter_type t4,
0531         typename access_traits<T5>::parameter_type t5)
0532     : inherited(t0, t1, t2, t3, t4, t5, detail::cnull(), detail::cnull(),
0533                 detail::cnull(), detail::cnull()) {}
0534 
0535   tuple(typename access_traits<T0>::parameter_type t0,
0536         typename access_traits<T1>::parameter_type t1,
0537         typename access_traits<T2>::parameter_type t2,
0538         typename access_traits<T3>::parameter_type t3,
0539         typename access_traits<T4>::parameter_type t4,
0540         typename access_traits<T5>::parameter_type t5,
0541         typename access_traits<T6>::parameter_type t6)
0542     : inherited(t0, t1, t2, t3, t4, t5, t6, detail::cnull(),
0543                 detail::cnull(), detail::cnull()) {}
0544 
0545   tuple(typename access_traits<T0>::parameter_type t0,
0546         typename access_traits<T1>::parameter_type t1,
0547         typename access_traits<T2>::parameter_type t2,
0548         typename access_traits<T3>::parameter_type t3,
0549         typename access_traits<T4>::parameter_type t4,
0550         typename access_traits<T5>::parameter_type t5,
0551         typename access_traits<T6>::parameter_type t6,
0552         typename access_traits<T7>::parameter_type t7)
0553     : inherited(t0, t1, t2, t3, t4, t5, t6, t7, detail::cnull(),
0554                 detail::cnull()) {}
0555 
0556   tuple(typename access_traits<T0>::parameter_type t0,
0557         typename access_traits<T1>::parameter_type t1,
0558         typename access_traits<T2>::parameter_type t2,
0559         typename access_traits<T3>::parameter_type t3,
0560         typename access_traits<T4>::parameter_type t4,
0561         typename access_traits<T5>::parameter_type t5,
0562         typename access_traits<T6>::parameter_type t6,
0563         typename access_traits<T7>::parameter_type t7,
0564         typename access_traits<T8>::parameter_type t8)
0565     : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, detail::cnull()) {}
0566 
0567   tuple(typename access_traits<T0>::parameter_type t0,
0568         typename access_traits<T1>::parameter_type t1,
0569         typename access_traits<T2>::parameter_type t2,
0570         typename access_traits<T3>::parameter_type t3,
0571         typename access_traits<T4>::parameter_type t4,
0572         typename access_traits<T5>::parameter_type t5,
0573         typename access_traits<T6>::parameter_type t6,
0574         typename access_traits<T7>::parameter_type t7,
0575         typename access_traits<T8>::parameter_type t8,
0576         typename access_traits<T9>::parameter_type t9)
0577     : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {}
0578 
0579 
0580   template<class U1, class U2>
0581   tuple(const cons<U1, U2>& p) : inherited(p) {}
0582 
0583   template <class U1, class U2>
0584   tuple& operator=(const cons<U1, U2>& k) {
0585     inherited::operator=(k);
0586     return *this;
0587   }
0588 
0589   template <class U1, class U2>
0590   tuple& operator=(const std::pair<U1, U2>& k) {
0591     BOOST_STATIC_ASSERT(length<tuple>::value == 2);// check_length = 2
0592     this->head = k.first;
0593     this->tail.head = k.second;
0594     return *this;
0595   }
0596 
0597 };
0598 
0599 // The empty tuple
0600 template <>
0601 class tuple<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type>  :
0602   public null_type
0603 {
0604 public:
0605   typedef null_type inherited;
0606 };
0607 
0608 
0609 // Swallows any assignment   (by Doug Gregor)
0610 namespace detail {
0611 
0612 struct swallow_assign;
0613 typedef void (detail::swallow_assign::*ignore_t)();
0614 struct swallow_assign {
0615   swallow_assign(ignore_t(*)(ignore_t)) {}
0616   template<typename T>
0617   swallow_assign const& operator=(const T&) const {
0618     return *this;
0619   }
0620 };
0621 
0622 
0623 } // namespace detail
0624 
0625 // "ignore" allows tuple positions to be ignored when using "tie".
0626 inline detail::ignore_t ignore(detail::ignore_t) { return 0; }
0627 
0628 // ---------------------------------------------------------------------------
0629 // The call_traits for make_tuple
0630 // Honours the reference_wrapper class.
0631 
0632 // Must be instantiated with plain or const plain types (not with references)
0633 
0634 // from template<class T> foo(const T& t) : make_tuple_traits<const T>::type
0635 // from template<class T> foo(T& t) : make_tuple_traits<T>::type
0636 
0637 // Conversions:
0638 // T -> T,
0639 // references -> compile_time_error
0640 // reference_wrapper<T> -> T&
0641 // const reference_wrapper<T> -> T&
0642 // array -> const ref array
0643 
0644 
0645 template<class T>
0646 struct make_tuple_traits {
0647   typedef T type;
0648 
0649   // commented away, see below  (JJ)
0650   //  typedef typename IF<
0651   //  boost::is_function<T>::value,
0652   //  T&,
0653   //  T>::RET type;
0654 
0655 };
0656 
0657 // The is_function test was there originally for plain function types,
0658 // which can't be stored as such (we must either store them as references or
0659 // pointers). Such a type could be formed if make_tuple was called with a
0660 // reference to a function.
0661 // But this would mean that a const qualified function type was formed in
0662 // the make_tuple function and hence make_tuple can't take a function
0663 // reference as a parameter, and thus T can't be a function type.
0664 // So is_function test was removed.
0665 // (14.8.3. says that type deduction fails if a cv-qualified function type
0666 // is created. (It only applies for the case of explicitly specifying template
0667 // args, though?)) (JJ)
0668 
0669 template<class T>
0670 struct make_tuple_traits<T&> {
0671   typedef typename
0672      detail::generate_error<T&>::
0673        do_not_use_with_reference_type error;
0674 };
0675 
0676 // Arrays can't be stored as plain types; convert them to references.
0677 // All arrays are converted to const. This is because make_tuple takes its
0678 // parameters as const T& and thus the knowledge of the potential
0679 // non-constness of actual argument is lost.
0680 template<class T, std::size_t n>  struct make_tuple_traits <T[n]> {
0681   typedef const T (&type)[n];
0682 };
0683 
0684 template<class T, std::size_t n>
0685 struct make_tuple_traits<const T[n]> {
0686   typedef const T (&type)[n];
0687 };
0688 
0689 template<class T, std::size_t n>  struct make_tuple_traits<volatile T[n]> {
0690   typedef const volatile T (&type)[n];
0691 };
0692 
0693 template<class T, std::size_t n>
0694 struct make_tuple_traits<const volatile T[n]> {
0695   typedef const volatile T (&type)[n];
0696 };
0697 
0698 template<class T>
0699 struct make_tuple_traits<reference_wrapper<T> >{
0700   typedef T& type;
0701 };
0702 
0703 template<class T>
0704 struct make_tuple_traits<const reference_wrapper<T> >{
0705   typedef T& type;
0706 };
0707 
0708 template<>
0709 struct make_tuple_traits<detail::ignore_t(detail::ignore_t)> {
0710   typedef detail::swallow_assign type;
0711 };
0712 
0713 
0714 
0715 namespace detail {
0716 
0717 // a helper traits to make the make_tuple functions shorter (Vesa Karvonen's
0718 // suggestion)
0719 template <
0720   class T0 = null_type, class T1 = null_type, class T2 = null_type,
0721   class T3 = null_type, class T4 = null_type, class T5 = null_type,
0722   class T6 = null_type, class T7 = null_type, class T8 = null_type,
0723   class T9 = null_type
0724 >
0725 struct make_tuple_mapper {
0726   typedef
0727     tuple<typename make_tuple_traits<T0>::type,
0728           typename make_tuple_traits<T1>::type,
0729           typename make_tuple_traits<T2>::type,
0730           typename make_tuple_traits<T3>::type,
0731           typename make_tuple_traits<T4>::type,
0732           typename make_tuple_traits<T5>::type,
0733           typename make_tuple_traits<T6>::type,
0734           typename make_tuple_traits<T7>::type,
0735           typename make_tuple_traits<T8>::type,
0736           typename make_tuple_traits<T9>::type> type;
0737 };
0738 
0739 } // end detail
0740 
0741 // -make_tuple function templates -----------------------------------
0742 inline tuple<> make_tuple() {
0743   return tuple<>();
0744 }
0745 
0746 template<class T0>
0747 inline typename detail::make_tuple_mapper<T0>::type
0748 make_tuple(const T0& t0) {
0749   typedef typename detail::make_tuple_mapper<T0>::type t;
0750   return t(t0);
0751 }
0752 
0753 template<class T0, class T1>
0754 inline typename detail::make_tuple_mapper<T0, T1>::type
0755 make_tuple(const T0& t0, const T1& t1) {
0756   typedef typename detail::make_tuple_mapper<T0, T1>::type t;
0757   return t(t0, t1);
0758 }
0759 
0760 template<class T0, class T1, class T2>
0761 inline typename detail::make_tuple_mapper<T0, T1, T2>::type
0762 make_tuple(const T0& t0, const T1& t1, const T2& t2) {
0763   typedef typename detail::make_tuple_mapper<T0, T1, T2>::type t;
0764   return t(t0, t1, t2);
0765 }
0766 
0767 template<class T0, class T1, class T2, class T3>
0768 inline typename detail::make_tuple_mapper<T0, T1, T2, T3>::type
0769 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3) {
0770   typedef typename detail::make_tuple_mapper<T0, T1, T2, T3>::type t;
0771   return t(t0, t1, t2, t3);
0772 }
0773 
0774 template<class T0, class T1, class T2, class T3, class T4>
0775 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type
0776 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
0777                   const T4& t4) {
0778   typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type t;
0779   return t(t0, t1, t2, t3, t4);
0780 }
0781 
0782 template<class T0, class T1, class T2, class T3, class T4, class T5>
0783 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type
0784 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
0785                   const T4& t4, const T5& t5) {
0786   typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type t;
0787   return t(t0, t1, t2, t3, t4, t5);
0788 }
0789 
0790 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
0791 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6>::type
0792 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
0793                   const T4& t4, const T5& t5, const T6& t6) {
0794   typedef typename detail::make_tuple_mapper
0795            <T0, T1, T2, T3, T4, T5, T6>::type t;
0796   return t(t0, t1, t2, t3, t4, t5, t6);
0797 }
0798 
0799 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
0800          class T7>
0801 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
0802 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
0803                   const T4& t4, const T5& t5, const T6& t6, const T7& t7) {
0804   typedef typename detail::make_tuple_mapper
0805            <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
0806   return t(t0, t1, t2, t3, t4, t5, t6, t7);
0807 }
0808 
0809 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
0810          class T7, class T8>
0811 inline typename detail::make_tuple_mapper
0812   <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
0813 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
0814                   const T4& t4, const T5& t5, const T6& t6, const T7& t7,
0815                   const T8& t8) {
0816   typedef typename detail::make_tuple_mapper
0817            <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
0818   return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
0819 }
0820 
0821 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
0822          class T7, class T8, class T9>
0823 inline typename detail::make_tuple_mapper
0824   <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
0825 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
0826                   const T4& t4, const T5& t5, const T6& t6, const T7& t7,
0827                   const T8& t8, const T9& t9) {
0828   typedef typename detail::make_tuple_mapper
0829            <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
0830   return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
0831 }
0832 
0833 namespace detail {
0834 
0835 template<class T>
0836 struct tie_traits {
0837   typedef T& type;
0838 };
0839 
0840 template<>
0841 struct tie_traits<ignore_t(ignore_t)> {
0842   typedef swallow_assign type;
0843 };
0844 
0845 template<>
0846 struct tie_traits<void> {
0847   typedef null_type type;
0848 };
0849 
0850 template <
0851   class T0 = void, class T1 = void, class T2 = void,
0852   class T3 = void, class T4 = void, class T5 = void,
0853   class T6 = void, class T7 = void, class T8 = void,
0854   class T9 = void
0855 >
0856 struct tie_mapper {
0857   typedef
0858     tuple<typename tie_traits<T0>::type,
0859           typename tie_traits<T1>::type,
0860           typename tie_traits<T2>::type,
0861           typename tie_traits<T3>::type,
0862           typename tie_traits<T4>::type,
0863           typename tie_traits<T5>::type,
0864           typename tie_traits<T6>::type,
0865           typename tie_traits<T7>::type,
0866           typename tie_traits<T8>::type,
0867           typename tie_traits<T9>::type> type;
0868 };
0869 
0870 }
0871 
0872 // Tie function templates -------------------------------------------------
0873 template<class T0>
0874 inline typename detail::tie_mapper<T0>::type
0875 tie(T0& t0) {
0876   typedef typename detail::tie_mapper<T0>::type t;
0877   return t(t0);
0878 }
0879 
0880 template<class T0, class T1>
0881 inline typename detail::tie_mapper<T0, T1>::type
0882 tie(T0& t0, T1& t1) {
0883   typedef typename detail::tie_mapper<T0, T1>::type t;
0884   return t(t0, t1);
0885 }
0886 
0887 template<class T0, class T1, class T2>
0888 inline typename detail::tie_mapper<T0, T1, T2>::type
0889 tie(T0& t0, T1& t1, T2& t2) {
0890   typedef typename detail::tie_mapper<T0, T1, T2>::type t;
0891   return t(t0, t1, t2);
0892 }
0893 
0894 template<class T0, class T1, class T2, class T3>
0895 inline typename detail::tie_mapper<T0, T1, T2, T3>::type
0896 tie(T0& t0, T1& t1, T2& t2, T3& t3) {
0897   typedef typename detail::tie_mapper<T0, T1, T2, T3>::type t;
0898   return t(t0, t1, t2, t3);
0899 }
0900 
0901 template<class T0, class T1, class T2, class T3, class T4>
0902 inline typename detail::tie_mapper<T0, T1, T2, T3, T4>::type
0903 tie(T0& t0, T1& t1, T2& t2, T3& t3,
0904                   T4& t4) {
0905   typedef typename detail::tie_mapper<T0, T1, T2, T3, T4>::type t;
0906   return t(t0, t1, t2, t3, t4);
0907 }
0908 
0909 template<class T0, class T1, class T2, class T3, class T4, class T5>
0910 inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type
0911 tie(T0& t0, T1& t1, T2& t2, T3& t3,
0912                   T4& t4, T5& t5) {
0913   typedef typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type t;
0914   return t(t0, t1, t2, t3, t4, t5);
0915 }
0916 
0917 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
0918 inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6>::type
0919 tie(T0& t0, T1& t1, T2& t2, T3& t3,
0920                   T4& t4, T5& t5, T6& t6) {
0921   typedef typename detail::tie_mapper
0922            <T0, T1, T2, T3, T4, T5, T6>::type t;
0923   return t(t0, t1, t2, t3, t4, t5, t6);
0924 }
0925 
0926 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
0927          class T7>
0928 inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
0929 tie(T0& t0, T1& t1, T2& t2, T3& t3,
0930                   T4& t4, T5& t5, T6& t6, T7& t7) {
0931   typedef typename detail::tie_mapper
0932            <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
0933   return t(t0, t1, t2, t3, t4, t5, t6, t7);
0934 }
0935 
0936 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
0937          class T7, class T8>
0938 inline typename detail::tie_mapper
0939   <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
0940 tie(T0& t0, T1& t1, T2& t2, T3& t3,
0941                   T4& t4, T5& t5, T6& t6, T7& t7,
0942                   T8& t8) {
0943   typedef typename detail::tie_mapper
0944            <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
0945   return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
0946 }
0947 
0948 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
0949          class T7, class T8, class T9>
0950 inline typename detail::tie_mapper
0951   <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
0952 tie(T0& t0, T1& t1, T2& t2, T3& t3,
0953                   T4& t4, T5& t5, T6& t6, T7& t7,
0954                   T8& t8, T9& t9) {
0955   typedef typename detail::tie_mapper
0956            <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
0957   return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
0958 }
0959 
0960 template <class T0, class T1, class T2, class T3, class T4,
0961           class T5, class T6, class T7, class T8, class T9>
0962 void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
0963           tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs);
0964 inline void swap(null_type&, null_type&) {}
0965 template<class HH>
0966 inline void swap(cons<HH, null_type>& lhs, cons<HH, null_type>& rhs) {
0967   ::boost::core::invoke_swap(lhs.head, rhs.head);
0968 }
0969 template<class HH, class TT>
0970 inline void swap(cons<HH, TT>& lhs, cons<HH, TT>& rhs) {
0971   ::boost::core::invoke_swap(lhs.head, rhs.head);
0972   ::boost::tuples::swap(lhs.tail, rhs.tail);
0973 }
0974 template <class T0, class T1, class T2, class T3, class T4,
0975           class T5, class T6, class T7, class T8, class T9>
0976 inline void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
0977           tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs) {
0978   typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
0979   typedef typename tuple_type::inherited base;
0980   ::boost::tuples::swap(static_cast<base&>(lhs), static_cast<base&>(rhs));
0981 }
0982 
0983 } // end of namespace tuples
0984 } // end of namespace boost
0985 
0986 
0987 #if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
0988 #pragma GCC diagnostic pop
0989 #endif
0990 
0991 
0992 #endif // BOOST_TUPLE_BASIC_HPP