From 894d0b150255d479c511373f975747df5e0ada8a Mon Sep 17 00:00:00 2001 From: Chris Fairles Date: Wed, 26 Dec 2007 15:23:49 +0000 Subject: [PATCH] tuple: New. 2007-12-26 Chris Fairles Paolo Carlini * include/std/tuple: New. * include/tr1/tuple: New, adjust from tr1_impl/tuple code. * include/tr1_impl/tuple: Remove. * include/Makefile.am: Update. * include/Makefile.in: Regenerate. Co-Authored-By: Paolo Carlini From-SVN: r131183 --- libstdc++-v3/ChangeLog | 9 + libstdc++-v3/include/Makefile.am | 1 - libstdc++-v3/include/Makefile.in | 1 - libstdc++-v3/include/std/tuple | 527 +++++++++++++++++++++++++++- libstdc++-v3/include/tr1/tuple | 409 ++++++++++++++++++++- libstdc++-v3/include/tr1_impl/tuple | 432 ----------------------- 6 files changed, 911 insertions(+), 468 deletions(-) delete mode 100644 libstdc++-v3/include/tr1_impl/tuple diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b870e820462..ae3ca7a33f6 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2007-12-26 Chris Fairles + Paolo Carlini + + * include/std/tuple: New. + * include/tr1/tuple: New, adjust from tr1_impl/tuple code. + * include/tr1_impl/tuple: Remove. + * include/Makefile.am: Update. + * include/Makefile.in: Regenerate. + 2007-12-25 Paolo Carlini * include/tr1_impl/hashtable_policy.h (__lower_bound): Add. diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index a4a4d3e481d..c955de1c19c 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -595,7 +595,6 @@ tr1_impl_headers = \ ${tr1_impl_srcdir}/random \ ${tr1_impl_srcdir}/random.tcc \ ${tr1_impl_srcdir}/regex \ - ${tr1_impl_srcdir}/tuple \ ${tr1_impl_srcdir}/type_traits \ ${tr1_impl_srcdir}/unordered_map \ ${tr1_impl_srcdir}/unordered_set \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 3291fca5607..afd8190551e 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -841,7 +841,6 @@ tr1_impl_headers = \ ${tr1_impl_srcdir}/random \ ${tr1_impl_srcdir}/random.tcc \ ${tr1_impl_srcdir}/regex \ - ${tr1_impl_srcdir}/tuple \ ${tr1_impl_srcdir}/type_traits \ ${tr1_impl_srcdir}/unordered_map \ ${tr1_impl_srcdir}/unordered_set \ diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 94e7ef5c086..1bec09152bd 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -40,24 +40,517 @@ # include #endif -#if defined(_GLIBCXX_INCLUDE_AS_TR1) -# error C++0x header cannot be included from TR1 header -#endif - #include -#if defined(_GLIBCXX_INCLUDE_AS_CXX0X) -# include -#else -# define _GLIBCXX_INCLUDE_AS_CXX0X -# define _GLIBCXX_BEGIN_NAMESPACE_TR1 -# define _GLIBCXX_END_NAMESPACE_TR1 -# define _GLIBCXX_TR1 -# include -# undef _GLIBCXX_TR1 -# undef _GLIBCXX_END_NAMESPACE_TR1 -# undef _GLIBCXX_BEGIN_NAMESPACE_TR1 -# undef _GLIBCXX_INCLUDE_AS_CXX0X -#endif +namespace std +{ + // Adds a const reference to a non-reference type. + template + struct __add_c_ref + { typedef const _Tp& type; }; + + template + struct __add_c_ref<_Tp&> + { typedef _Tp& type; }; + + // Adds a reference to a non-reference type. + template + struct __add_ref + { typedef _Tp& type; }; + + template + struct __add_ref<_Tp&> + { typedef _Tp& type; }; + + template + struct _Head_base; + + template + struct _Head_base<_Idx, _Head, true> + : public _Head + { + _Head_base() + : _Head() { } + + _Head_base(typename __add_c_ref<_Head>::type __h) + : _Head(__h) { } + + _Head_base(typename std::remove_reference<_Head>::type&& __h) + : _Head(std::forward<_Head>(__h)) { } + + _Head& _M_head() { return *this; } + const _Head& _M_head() const { return *this; } + }; + + template + struct _Head_base<_Idx, _Head, false> + { + _Head_base() + : _M_head_impl() { } + + _Head_base(typename __add_c_ref<_Head>::type __h) + : _M_head_impl(__h) { } + + _Head_base(typename std::remove_reference<_Head>::type&& __h) + : _M_head_impl(std::move(__h)) { } + + _Head& _M_head() { return _M_head_impl; } + const _Head& _M_head() const { return _M_head_impl; } + + _Head _M_head_impl; + }; + + /** + * @if maint + * Contains the actual implementation of the @c tuple template, stored + * as a recursive inheritance hierarchy from the first element (most + * derived class) to the last (least derived class). The @c Idx + * parameter gives the 0-based index of the element stored at this + * point in the hierarchy; we use it to implement a constant-time + * get() operation. + * @endif + */ + template + struct _Tuple_impl; + + /** + * @if maint + * Zero-element tuple implementation. This is the basis case for the + * inheritance recursion. + * @endif maint + */ + template + struct _Tuple_impl<_Idx> { }; + + /** + * @if maint + * Recursive tuple implementation. Here we store the @c Head element + * and derive from a @c Tuple_impl containing the remaining elements + * (which contains the @c Tail). + * @endif + */ + template + struct _Tuple_impl<_Idx, _Head, _Tail...> + : public _Tuple_impl<_Idx + 1, _Tail...>, + private _Head_base<_Idx, _Head, std::is_empty<_Head>::value> + { + typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; + typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base; + + _Head& _M_head() { return _Base::_M_head(); } + const _Head& _M_head() const { return _Base::_M_head(); } + + _Inherited& _M_tail() { return *this; } + const _Inherited& _M_tail() const { return *this; } + + _Tuple_impl() + : _Inherited(), _Base() { } + + explicit + _Tuple_impl(typename __add_c_ref<_Head>::type __head, + typename __add_c_ref<_Tail>::type... __tail) + : _Inherited(__tail...), _Base(__head) { } + + template + _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) + : _Inherited(__in._M_tail()), _Base(__in._M_head()) { } + + _Tuple_impl(const _Tuple_impl& __in) + : _Inherited(__in._M_tail()), _Base(__in._M_head()) { } + + template + _Tuple_impl& + operator=(const _Tuple_impl<_Idx, _UElements...>& __in) + { + _M_head() = __in._M_head(); + _M_tail() = __in._M_tail(); + return *this; + } + + _Tuple_impl& + operator=(const _Tuple_impl& __in) + { + _M_head() = __in._M_head(); + _M_tail() = __in._M_tail(); + return *this; + } + }; + + template + class tuple : public _Tuple_impl<0, _Elements...> + { + typedef _Tuple_impl<0, _Elements...> _Inherited; + + public: + tuple() + : _Inherited() { } + + explicit + tuple(typename __add_c_ref<_Elements>::type... __elements) + : _Inherited(__elements...) { } + + template + tuple(const tuple<_UElements...>& __in) + : _Inherited(__in) { } + + tuple(const tuple& __in) + : _Inherited(__in) { } + + template + tuple& + operator=(const tuple<_UElements...>& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + tuple& + operator=(const tuple& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + }; + + template<> class tuple<> { }; + + // 2-element tuple, with construction and assignment from a pair. + template + class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> + { + typedef _Tuple_impl<0, _T1, _T2> _Inherited; + + public: + tuple() + : _Inherited() { } + + explicit + tuple(typename __add_c_ref<_T1>::type __a1, + typename __add_c_ref<_T2>::type __a2) + : _Inherited(__a1, __a2) { } + + template + tuple(const tuple<_U1, _U2>& __in) + : _Inherited(__in) { } + + tuple(const tuple& __in) + : _Inherited(__in) { } + + template + tuple(const pair<_U1, _U2>& __in) + : _Inherited(_Tuple_impl<0, + typename __add_c_ref<_U1>::type, + typename __add_c_ref<_U2>::type>(__in.first, + __in.second)) + { } + + template + tuple& + operator=(const tuple<_U1, _U2>& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + tuple& + operator=(const tuple& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + template + tuple& + operator=(const pair<_U1, _U2>& __in) + { + this->_M_head() = __in.first; + this->_M_tail()._M_head() = __in.second; + return *this; + } + }; + + + /// Gives the type of the ith element of a given tuple type. + template + struct tuple_element; + + /** + * @if maint + * Recursive case for tuple_element: strip off the first element in + * the tuple and retrieve the (i-1)th element of the remaining tuple. + * @endif + */ + template + struct tuple_element<__i, tuple<_Head, _Tail...> > + : tuple_element<__i - 1, tuple<_Tail...> > { }; + + /** + * @if maint + * Basis case for tuple_element: The first element is the one we're seeking. + * @endif + */ + template + struct tuple_element<0, tuple<_Head, _Tail...> > + { + typedef _Head type; + }; + + /// Finds the size of a given tuple type. + template + struct tuple_size; + + /// @brief class tuple_size + template + struct tuple_size > + { + static const int value = sizeof...(_Elements); + }; + + template + const int tuple_size >::value; + + template + inline typename __add_ref<_Head>::type + __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) + { return __t._M_head(); } + + template + inline typename __add_c_ref<_Head>::type + __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) + { return __t._M_head(); } + + // Return a reference (const reference) to the ith element of a tuple. + // Any const or non-const ref elements are returned with their original type. + template + inline typename __add_ref< + typename tuple_element<__i, tuple<_Elements...> >::type + >::type + get(tuple<_Elements...>& __t) + { return __get_helper<__i>(__t); } + + template + inline typename __add_c_ref< + typename tuple_element<__i, tuple<_Elements...> >::type + >::type + get(const tuple<_Elements...>& __t) + { return __get_helper<__i>(__t); } + + // This class helps construct the various comparison operations on tuples + template + struct __tuple_compare; + + template + struct __tuple_compare<0, __i, __j, _Tp, _Up> + { + static bool __eq(const _Tp& __t, const _Up& __u) + { + return (get<__i>(__t) == get<__i>(__u) && + __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u)); + } + + static bool __less(const _Tp& __t, const _Up& __u) + { + return ((get<__i>(__t) < get<__i>(__u)) + || !(get<__i>(__u) < get<__i>(__t)) && + __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u)); + } + }; + + template + struct __tuple_compare<0, __i, __i, _Tp, _Up> + { + static bool __eq(const _Tp&, const _Up&) + { return true; } + + static bool __less(const _Tp&, const _Up&) + { return false; } + }; + + template + bool + operator==(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { + typedef tuple<_TElements...> _Tp; + typedef tuple<_UElements...> _Up; + return (__tuple_compare::value - tuple_size<_Tp>::value, + 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); + } + + template + bool + operator<(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { + typedef tuple<_TElements...> _Tp; + typedef tuple<_UElements...> _Up; + return (__tuple_compare::value - tuple_size<_Tp>::value, + 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); + } + + template + inline bool + operator!=(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return !(__t == __u); } + + template + inline bool + operator>(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return __u < __t; } + + template + inline bool + operator<=(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return !(__u < __t); } + + template + inline bool + operator>=(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return !(__t < __u); } + + // NB: DR 705. + template + inline tuple::__type...> + make_tuple(_Elements&&... __args) + { + typedef tuple::__type...> + __result_type; + return __result_type(std::forward<_Elements>(__args)...); + } + + template struct __index_holder { }; + + template + struct __index_holder_impl; + + template + struct __index_holder_impl<__i, __index_holder<_Indexes...>, + _IdxHolder, _Elements...> + { + typedef typename __index_holder_impl<__i + 1, + __index_holder<_Indexes..., __i>, + _Elements...>::type type; + }; + + template + struct __index_holder_impl<__i, __index_holder<_Indexes...> > + { typedef __index_holder<_Indexes...> type; }; + + template + struct __make_index_holder + : __index_holder_impl<0, __index_holder<>, _Elements...> { }; + + template + inline tuple<_TElements..., _UElements...> + __tuple_cat_helper(const tuple<_TElements...>& __t, + const __index_holder<_TIdx...>&, + const tuple<_UElements...>& __u, + const __index_holder<_UIdx...>&) + { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)..., + get<_UIdx>(__u)...); } + + template + inline tuple<_TElements..., _UElements...> + __tuple_cat_helper(tuple<_TElements...>&& __t, + const __index_holder<_TIdx...>&, + const tuple<_UElements...>& __u, + const __index_holder<_UIdx...>&) + { return tuple<_TElements..., _UElements...>(std::move(get<_TIdx>(__t))..., + get<_UIdx>(__u)...); } + + template + inline tuple<_TElements..., _UElements...> + __tuple_cat_helper(const tuple<_TElements...>& __t, + const __index_holder<_TIdx...>&, + tuple<_UElements...>&& __u, + const __index_holder<_UIdx...>&) + { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)..., + std::move(get<_UIdx>(__u))...); } + + template + inline tuple<_TElements..., _UElements...> + __tuple_cat_helper(tuple<_TElements...>&& __t, + const __index_holder<_TIdx...>&, + tuple<_UElements...>&& __u, + const __index_holder<_UIdx...>&) + { return tuple<_TElements..., _UElements...>(std::move(get<_TIdx>(__t))..., + std::move(get<_UIdx>(__u))...); } + + template + inline tuple<_TElements..., _UElements...> + tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) + { + return __tuple_cat_helper(__t, typename + __make_index_holder<_TElements...>::type(), + __u, typename + __make_index_holder<_UElements...>::type()); + } + + template + inline tuple<_TElements..., _UElements...> + tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u) + { + return __tuple_cat_helper(std::move(__t), typename + __make_index_holder<_TElements...>::type(), + __u, typename + __make_index_holder<_UElements...>::type()); + } + + template + inline tuple<_TElements..., _UElements...> + tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u) + { + return __tuple_cat_helper(__t, typename + __make_index_holder<_TElements...>::type(), + std::move(__u), typename + __make_index_holder<_UElements...>::type()); + } + + template + inline tuple<_TElements..., _UElements...> + tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u) + { + return __tuple_cat_helper(std::move(__t), typename + __make_index_holder<_TElements...>::type(), + std::move(__u), typename + __make_index_holder<_UElements...>::type()); + } + + template + tuple<_TElements..., _UElements...> + operator+(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u) + { return tuple_cat(std::forward(__t), + std::forward(__u)); } + + template + inline tuple<_Elements&...> + tie(_Elements&... __args) + { return tuple<_Elements&...>(__args...); } + + // A class (and instance) which can be used in 'tie' when an element + // of a tuple is not required + struct _Swallow_assign + { + template + _Swallow_assign& + operator=(const _Tp&) + { return *this; } + }; + + // TODO: Put this in some kind of shared file. + namespace + { + _Swallow_assign ignore; + }; // anonymous namespace +} #endif // _GLIBCXX_CXX0X_TUPLE diff --git a/libstdc++-v3/include/tr1/tuple b/libstdc++-v3/include/tr1/tuple index 0c7ed3f60ae..b342fc3674e 100644 --- a/libstdc++-v3/include/tr1/tuple +++ b/libstdc++-v3/include/tr1/tuple @@ -39,24 +39,399 @@ #pragma GCC system_header -#if defined(_GLIBCXX_INCLUDE_AS_CXX0X) -# error TR1 header cannot be included from C++0x header -#endif - #include -#if defined(_GLIBCXX_INCLUDE_AS_TR1) -# include -#else -# define _GLIBCXX_INCLUDE_AS_TR1 -# define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 { -# define _GLIBCXX_END_NAMESPACE_TR1 } -# define _GLIBCXX_TR1 tr1:: -# include -# undef _GLIBCXX_TR1 -# undef _GLIBCXX_END_NAMESPACE_TR1 -# undef _GLIBCXX_BEGIN_NAMESPACE_TR1 -# undef _GLIBCXX_INCLUDE_AS_TR1 -#endif +namespace std +{ +namespace tr1 +{ + // Adds a const reference to a non-reference type. + template + struct __add_c_ref + { typedef const _Tp& type; }; + + template + struct __add_c_ref<_Tp&> + { typedef _Tp& type; }; + + // Adds a reference to a non-reference type. + template + struct __add_ref + { typedef _Tp& type; }; + + template + struct __add_ref<_Tp&> + { typedef _Tp& type; }; + + /** + * @if maint + * Contains the actual implementation of the @c tuple template, stored + * as a recursive inheritance hierarchy from the first element (most + * derived class) to the last (least derived class). The @c Idx + * parameter gives the 0-based index of the element stored at this + * point in the hierarchy; we use it to implement a constant-time + * get() operation. + * @endif + */ + template + struct _Tuple_impl; + + /** + * @if maint + * Zero-element tuple implementation. This is the basis case for the + * inheritance recursion. + * @endif maint + */ + template + struct _Tuple_impl<_Idx> { }; + + /** + * @if maint + * Recursive tuple implementation. Here we store the @c Head element + * and derive from a @c Tuple_impl containing the remaining elements + * (which contains the @c Tail). + * @endif + */ + template + struct _Tuple_impl<_Idx, _Head, _Tail...> + : public _Tuple_impl<_Idx + 1, _Tail...> + { + typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; + + _Head _M_head; + + _Inherited& _M_tail() { return *this; } + const _Inherited& _M_tail() const { return *this; } + + _Tuple_impl() : _Inherited(), _M_head() { } + + explicit + _Tuple_impl(typename __add_c_ref<_Head>::type __head, + typename __add_c_ref<_Tail>::type... __tail) + : _Inherited(__tail...), _M_head(__head) { } + + template + _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) + : _Inherited(__in._M_tail()), _M_head(__in._M_head) { } + + _Tuple_impl(const _Tuple_impl& __in) + : _Inherited(__in._M_tail()), _M_head(__in._M_head) { } + + template + _Tuple_impl& + operator=(const _Tuple_impl<_Idx, _UElements...>& __in) + { + _M_head = __in._M_head; + _M_tail() = __in._M_tail(); + return *this; + } + + _Tuple_impl& + operator=(const _Tuple_impl& __in) + { + _M_head = __in._M_head; + _M_tail() = __in._M_tail(); + return *this; + } + }; + + template + class tuple : public _Tuple_impl<0, _Elements...> + { + typedef _Tuple_impl<0, _Elements...> _Inherited; + + public: + tuple() : _Inherited() { } + + explicit + tuple(typename __add_c_ref<_Elements>::type... __elements) + : _Inherited(__elements...) { } + + template + tuple(const tuple<_UElements...>& __in) + : _Inherited(__in) { } + + tuple(const tuple& __in) + : _Inherited(__in) { } + + template + tuple& + operator=(const tuple<_UElements...>& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + tuple& + operator=(const tuple& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + }; + + template<> class tuple<> { }; + + // 2-element tuple, with construction and assignment from a pair. + template + class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> + { + typedef _Tuple_impl<0, _T1, _T2> _Inherited; + + public: + tuple() : _Inherited() { } + + explicit + tuple(typename __add_c_ref<_T1>::type __a1, + typename __add_c_ref<_T2>::type __a2) + : _Inherited(__a1, __a2) { } + + template + tuple(const tuple<_U1, _U2>& __in) + : _Inherited(__in) { } + + tuple(const tuple& __in) + : _Inherited(__in) { } + + template + tuple(const pair<_U1, _U2>& __in) + : _Inherited(_Tuple_impl<0, + typename __add_c_ref<_U1>::type, + typename __add_c_ref<_U2>::type>(__in.first, + __in.second)) + { } + + template + tuple& + operator=(const tuple<_U1, _U2>& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + tuple& + operator=(const tuple& __in) + { + static_cast<_Inherited&>(*this) = __in; + return *this; + } + + template + tuple& + operator=(const pair<_U1, _U2>& __in) + { + this->_M_head = __in.first; + this->_M_tail()._M_head = __in.second; + return *this; + } + }; + + + /// Gives the type of the ith element of a given tuple type. + template + struct tuple_element; + + /** + * @if maint + * Recursive case for tuple_element: strip off the first element in + * the tuple and retrieve the (i-1)th element of the remaining tuple. + * @endif + */ + template + struct tuple_element<__i, tuple<_Head, _Tail...> > + : tuple_element<__i - 1, tuple<_Tail...> > { }; + + /** + * @if maint + * Basis case for tuple_element: The first element is the one we're seeking. + * @endif + */ + template + struct tuple_element<0, tuple<_Head, _Tail...> > + { + typedef _Head type; + }; + + /// Finds the size of a given tuple type. + template + struct tuple_size; + + /// @brief class tuple_size + template + struct tuple_size > + { + static const int value = sizeof...(_Elements); + }; + + template + const int tuple_size >::value; + + template + inline typename __add_ref<_Head>::type + __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) + { + return __t._M_head; + } + + template + inline typename __add_c_ref<_Head>::type + __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) + { + return __t._M_head; + } + + // Return a reference (const reference) to the ith element of a tuple. + // Any const or non-const ref elements are returned with their original type. + template + inline typename __add_ref< + typename tuple_element<__i, tuple<_Elements...> >::type + >::type + get(tuple<_Elements...>& __t) + { + return __get_helper<__i>(__t); + } + + template + inline typename __add_c_ref< + typename tuple_element<__i, tuple<_Elements...> >::type + >::type + get(const tuple<_Elements...>& __t) + { + return __get_helper<__i>(__t); + } + + // This class helps construct the various comparison operations on tuples + template + struct __tuple_compare; + + template + struct __tuple_compare<0, __i, __j, _Tp, _Up> + { + static bool __eq(const _Tp& __t, const _Up& __u) + { + return (get<__i>(__t) == get<__i>(__u) && + __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u)); + } + + static bool __less(const _Tp& __t, const _Up& __u) + { + return ((get<__i>(__t) < get<__i>(__u)) + || !(get<__i>(__u) < get<__i>(__t)) && + __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u)); + } + }; + + template + struct __tuple_compare<0, __i, __i, _Tp, _Up> + { + static bool __eq(const _Tp&, const _Up&) + { return true; } + + static bool __less(const _Tp&, const _Up&) + { return false; } + }; + + template + bool + operator==(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { + typedef tuple<_TElements...> _Tp; + typedef tuple<_UElements...> _Up; + return (__tuple_compare::value - tuple_size<_Tp>::value, + 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); + } + + template + bool + operator<(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { + typedef tuple<_TElements...> _Tp; + typedef tuple<_UElements...> _Up; + return (__tuple_compare::value - tuple_size<_Tp>::value, + 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); + } + + template + inline bool + operator!=(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return !(__t == __u); } + + template + inline bool + operator>(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return __u < __t; } + + template + inline bool + operator<=(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return !(__u < __t); } + + template + inline bool + operator>=(const tuple<_TElements...>& __t, + const tuple<_UElements...>& __u) + { return !(__t < __u); } + + template + class reference_wrapper; + + // Helper which adds a reference to a type when given a reference_wrapper + template + struct __strip_reference_wrapper + { + typedef _Tp __type; + }; + + template + struct __strip_reference_wrapper > + { + typedef _Tp& __type; + }; + + template + struct __strip_reference_wrapper > + { + typedef _Tp& __type; + }; + + template + inline tuple::__type...> + make_tuple(_Elements... __args) + { + typedef tuple::__type...> + __result_type; + return __result_type(__args...); + } + + template + inline tuple<_Elements&...> + tie(_Elements&... __args) + { + return tuple<_Elements&...>(__args...); + } + + // A class (and instance) which can be used in 'tie' when an element + // of a tuple is not required + struct _Swallow_assign + { + template + _Swallow_assign& + operator=(const _Tp&) + { return *this; } + }; + + // TODO: Put this in some kind of shared file. + namespace + { + _Swallow_assign ignore; + }; // anonymous namespace +} +} #endif // _GLIBCXX_TR1_TUPLE diff --git a/libstdc++-v3/include/tr1_impl/tuple b/libstdc++-v3/include/tr1_impl/tuple deleted file mode 100644 index e71bd4174c2..00000000000 --- a/libstdc++-v3/include/tr1_impl/tuple +++ /dev/null @@ -1,432 +0,0 @@ -// class template tuple -*- C++ -*- - -// Copyright (C) 2007 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -// USA. - -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. - -/** @file tr1_impl/tuple - * This is an internal header file, included by other library headers. - * You should not attempt to use it directly. -*/ - -// Chris Jefferson -// Variadic Templates support by Douglas Gregor - -namespace std -{ -_GLIBCXX_BEGIN_NAMESPACE_TR1 - - // Adds a const reference to a non-reference type. - template - struct __add_c_ref - { typedef const _Tp& type; }; - - template - struct __add_c_ref<_Tp&> - { typedef _Tp& type; }; - - // Adds a reference to a non-reference type. - template - struct __add_ref - { typedef _Tp& type; }; - - template - struct __add_ref<_Tp&> - { typedef _Tp& type; }; - - /** - * @if maint - * Contains the actual implementation of the @c tuple template, stored - * as a recursive inheritance hierarchy from the first element (most - * derived class) to the last (least derived class). The @c Idx - * parameter gives the 0-based index of the element stored at this - * point in the hierarchy; we use it to implement a constant-time - * get() operation. - * @endif - */ - template - struct _Tuple_impl; - - /** - * @if maint - * Zero-element tuple implementation. This is the basis case for the - * inheritance recursion. - * @endif maint - */ - template - struct _Tuple_impl<_Idx> { }; - - /** - * @if maint - * Recursive tuple implementation. Here we store the @c Head element - * and derive from a @c Tuple_impl containing the remaining elements - * (which contains the @c Tail). - * @endif - */ - template - struct _Tuple_impl<_Idx, _Head, _Tail...> - : public _Tuple_impl<_Idx + 1, _Tail...> - { - typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; - - _Head _M_head; - - _Inherited& _M_tail() { return *this; } - const _Inherited& _M_tail() const { return *this; } - - _Tuple_impl() : _Inherited(), _M_head() { } - - explicit - _Tuple_impl(typename __add_c_ref<_Head>::type __head, - typename __add_c_ref<_Tail>::type... __tail) - : _Inherited(__tail...), _M_head(__head) { } - - template - _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) - : _Inherited(__in._M_tail()), _M_head(__in._M_head) { } - - _Tuple_impl(const _Tuple_impl& __in) - : _Inherited(__in._M_tail()), _M_head(__in._M_head) { } - - template - _Tuple_impl& - operator=(const _Tuple_impl<_Idx, _UElements...>& __in) - { - _M_head = __in._M_head; - _M_tail() = __in._M_tail(); - return *this; - } - - _Tuple_impl& - operator=(const _Tuple_impl& __in) - { - _M_head = __in._M_head; - _M_tail() = __in._M_tail(); - return *this; - } - }; - - template - class tuple : public _Tuple_impl<0, _Elements...> - { - typedef _Tuple_impl<0, _Elements...> _Inherited; - - public: - tuple() : _Inherited() { } - - explicit - tuple(typename __add_c_ref<_Elements>::type... __elements) - : _Inherited(__elements...) { } - - template - tuple(const tuple<_UElements...>& __in) - : _Inherited(__in) { } - - tuple(const tuple& __in) - : _Inherited(__in) { } - - template - tuple& - operator=(const tuple<_UElements...>& __in) - { - static_cast<_Inherited&>(*this) = __in; - return *this; - } - - tuple& - operator=(const tuple& __in) - { - static_cast<_Inherited&>(*this) = __in; - return *this; - } - }; - - template<> class tuple<> { }; - - // 2-element tuple, with construction and assignment from a pair. - template - class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> - { - typedef _Tuple_impl<0, _T1, _T2> _Inherited; - - public: - tuple() : _Inherited() { } - - explicit - tuple(typename __add_c_ref<_T1>::type __a1, - typename __add_c_ref<_T2>::type __a2) - : _Inherited(__a1, __a2) { } - - template - tuple(const tuple<_U1, _U2>& __in) - : _Inherited(__in) { } - - tuple(const tuple& __in) - : _Inherited(__in) { } - - template - tuple(const pair<_U1, _U2>& __in) - : _Inherited(_Tuple_impl<0, - typename __add_c_ref<_U1>::type, - typename __add_c_ref<_U2>::type>(__in.first, - __in.second)) - { } - - template - tuple& - operator=(const tuple<_U1, _U2>& __in) - { - static_cast<_Inherited&>(*this) = __in; - return *this; - } - - tuple& - operator=(const tuple& __in) - { - static_cast<_Inherited&>(*this) = __in; - return *this; - } - - template - tuple& - operator=(const pair<_U1, _U2>& __in) - { - this->_M_head = __in.first; - this->_M_tail()._M_head = __in.second; - return *this; - } - }; - - - /// Gives the type of the ith element of a given tuple type. - template - struct tuple_element; - - /** - * @if maint - * Recursive case for tuple_element: strip off the first element in - * the tuple and retrieve the (i-1)th element of the remaining tuple. - * @endif - */ - template - struct tuple_element<__i, tuple<_Head, _Tail...> > - : tuple_element<__i - 1, tuple<_Tail...> > { }; - - /** - * @if maint - * Basis case for tuple_element: The first element is the one we're seeking. - * @endif - */ - template - struct tuple_element<0, tuple<_Head, _Tail...> > - { - typedef _Head type; - }; - - /// Finds the size of a given tuple type. - template - struct tuple_size; - - /// @brief class tuple_size - template - struct tuple_size > - { - static const int value = sizeof...(_Elements); - }; - - template - const int tuple_size >::value; - - template - inline typename __add_ref<_Head>::type - __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) - { - return __t._M_head; - } - - template - inline typename __add_c_ref<_Head>::type - __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) - { - return __t._M_head; - } - - // Return a reference (const reference) to the ith element of a tuple. - // Any const or non-const ref elements are returned with their original type. - template - inline typename __add_ref< - typename tuple_element<__i, tuple<_Elements...> >::type - >::type - get(tuple<_Elements...>& __t) - { - return __get_helper<__i>(__t); - } - - template - inline typename __add_c_ref< - typename tuple_element<__i, tuple<_Elements...> >::type - >::type - get(const tuple<_Elements...>& __t) - { - return __get_helper<__i>(__t); - } - - // This class helps construct the various comparison operations on tuples - template - struct __tuple_compare; - - template - struct __tuple_compare<0, __i, __j, _Tp, _Up> - { - static bool __eq(const _Tp& __t, const _Up& __u) - { - return (get<__i>(__t) == get<__i>(__u) && - __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u)); - } - - static bool __less(const _Tp& __t, const _Up& __u) - { - return ((get<__i>(__t) < get<__i>(__u)) - || !(get<__i>(__u) < get<__i>(__t)) && - __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u)); - } - }; - - template - struct __tuple_compare<0, __i, __i, _Tp, _Up> - { - static bool __eq(const _Tp&, const _Up&) - { return true; } - - static bool __less(const _Tp&, const _Up&) - { return false; } - }; - - template - bool - operator==(const tuple<_TElements...>& __t, - const tuple<_UElements...>& __u) - { - typedef tuple<_TElements...> _Tp; - typedef tuple<_UElements...> _Up; - return (__tuple_compare::value - tuple_size<_Tp>::value, - 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); - } - - template - bool - operator<(const tuple<_TElements...>& __t, - const tuple<_UElements...>& __u) - { - typedef tuple<_TElements...> _Tp; - typedef tuple<_UElements...> _Up; - return (__tuple_compare::value - tuple_size<_Tp>::value, - 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); - } - - template - bool - operator!=(const tuple<_TElements...>& __t, - const tuple<_UElements...>& __u) - { return !(__t == __u); } - - template - bool - operator>(const tuple<_TElements...>& __t, - const tuple<_UElements...>& __u) - { return __u < __t; } - - template - bool - operator<=(const tuple<_TElements...>& __t, - const tuple<_UElements...>& __u) - { return !(__u < __t); } - - template - bool - operator>=(const tuple<_TElements...>& __t, - const tuple<_UElements...>& __u) - { return !(__t < __u); } - -#ifdef _GLIBCXX_INCLUDE_AS_TR1 - template - class reference_wrapper; - - // Helper which adds a reference to a type when given a reference_wrapper - template - struct __strip_reference_wrapper - { - typedef _Tp __type; - }; - - template - struct __strip_reference_wrapper > - { - typedef _Tp& __type; - }; - - template - struct __strip_reference_wrapper > - { - typedef _Tp& __type; - }; -#endif - - template - inline tuple::__type...> - make_tuple(_Elements... __args) - { - typedef tuple::__type...> - __result_type; - return __result_type(__args...); - } - - template - inline tuple<_Elements&...> - tie(_Elements&... __args) - { - return tuple<_Elements&...>(__args...); - } - - // A class (and instance) which can be used in 'tie' when an element - // of a tuple is not required - struct _Swallow_assign - { - template - _Swallow_assign& - operator=(const _Tp&) - { return *this; } - }; - - // TODO: Put this in some kind of shared file. - namespace - { - _Swallow_assign ignore; - }; // anonymous namespace - -_GLIBCXX_END_NAMESPACE_TR1 -}