diff options
Diffstat (limited to 'libstdc++-v3/include/std/tuple')
-rw-r--r-- | libstdc++-v3/include/std/tuple | 155 |
1 files changed, 103 insertions, 52 deletions
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index fb452aeb43e..dc9330d0b59 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -59,6 +59,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __add_ref<_Tp&> { typedef _Tp& type; }; + // Adds an rvalue reference to a non-reference type. + template<typename _Tp> + struct __add_r_ref + { typedef _Tp&& type; }; + + template<typename _Tp> + struct __add_r_ref<_Tp&> + { typedef _Tp& type; }; + template<std::size_t _Idx, typename _Head, bool _IsEmpty> struct _Head_base; @@ -76,15 +85,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Head_base(_UHead&& __h) : _Head(std::forward<_UHead>(__h)) { } - _Head& _M_head() { return *this; } - const _Head& _M_head() const { return *this; } - - void - _M_swap_impl(_Head& __h) - { - using std::swap; - swap(__h, _M_head()); - } + _Head& _M_head() noexcept { return *this; } + const _Head& _M_head() const noexcept { return *this; } }; template<std::size_t _Idx, typename _Head> @@ -100,15 +102,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Head_base(_UHead&& __h) : _M_head_impl(std::forward<_UHead>(__h)) { } - _Head& _M_head() { return _M_head_impl; } - const _Head& _M_head() const { return _M_head_impl; } - - void - _M_swap_impl(_Head& __h) - { - using std::swap; - swap(__h, _M_head()); - } + _Head& _M_head() noexcept { return _M_head_impl; } + const _Head& _M_head() const noexcept { return _M_head_impl; } _Head _M_head_impl; }; @@ -130,9 +125,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<std::size_t _Idx> struct _Tuple_impl<_Idx> - { + { + template<std::size_t, typename...> friend class _Tuple_impl; + protected: - void _M_swap_impl(_Tuple_impl&) { /* no-op */ } + void _M_swap(_Tuple_impl&) noexcept { /* no-op */ } }; /** @@ -145,14 +142,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public _Tuple_impl<_Idx + 1, _Tail...>, private _Head_base<_Idx, _Head, std::is_empty<_Head>::value> { + template<std::size_t, typename...> friend class _Tuple_impl; + 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(); } + _Head& _M_head() noexcept { return _Base::_M_head(); } + const _Head& _M_head() const noexcept { return _Base::_M_head(); } - _Inherited& _M_tail() { return *this; } - const _Inherited& _M_tail() const { return *this; } + _Inherited& _M_tail() noexcept { return *this; } + const _Inherited& _M_tail() const noexcept { return *this; } constexpr _Tuple_impl() : _Inherited(), _Base() { } @@ -192,6 +191,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tuple_impl& operator=(_Tuple_impl&& __in) + noexcept(is_nothrow_move_assignable<_Head>::value + && is_nothrow_move_assignable<_Inherited>::value) { _M_head() = std::forward<_Head>(__in._M_head()); _M_tail() = std::move(__in._M_tail()); @@ -218,10 +219,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION protected: void - _M_swap_impl(_Tuple_impl& __in) + _M_swap(_Tuple_impl& __in) + noexcept(noexcept(swap(std::declval<_Head&>(), + std::declval<_Head&>())) + && noexcept(__in._M_tail()._M_swap(__in._M_tail()))) { - _Base::_M_swap_impl(__in._M_head()); - _Inherited::_M_swap_impl(__in._M_tail()); + using std::swap; + swap(this->_M_head(), __in._M_head()); + _Inherited::_M_swap(__in._M_tail()); } }; @@ -273,6 +278,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple& operator=(tuple&& __in) + noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; @@ -300,14 +306,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void swap(tuple& __in) - { _Inherited::_M_swap_impl(__in); } + noexcept(noexcept(__in._M_swap(__in))) + { _Inherited::_M_swap(__in); } }; template<> class tuple<> { public: - void swap(tuple&) { /* no-op */ } + void swap(tuple&) noexcept { /* no-op */ } }; /// tuple (2-element), with construction and assignment from a pair. @@ -360,6 +367,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple& operator=(tuple&& __in) + noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; @@ -401,11 +409,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void swap(tuple& __in) - { - using std::swap; - swap(this->_M_head(), __in._M_head()); - swap(this->_M_tail()._M_head(), __in._M_tail()._M_head()); - } + noexcept(noexcept(__in._M_swap(__in))) + { _Inherited::_M_swap(__in); } }; /// tuple (1-element). @@ -450,6 +455,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple& operator=(tuple&& __in) + noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); return *this; @@ -473,7 +479,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void swap(tuple& __in) - { _Inherited::_M_swap_impl(__in); } + noexcept(noexcept(__in._M_swap(__in))) + { _Inherited::_M_swap(__in); } }; @@ -498,46 +505,89 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Head type; }; + template<std::size_t __i, typename _Tp> + struct tuple_element<__i, const _Tp> + { + typedef typename + add_const<typename tuple_element<__i, _Tp>::type>::type type; + }; + + template<std::size_t __i, typename _Tp> + struct tuple_element<__i, volatile _Tp> + { + typedef typename + add_volatile<typename tuple_element<__i, _Tp>::type>::type type; + }; + + template<std::size_t __i, typename _Tp> + struct tuple_element<__i, const volatile _Tp> + { + typedef typename + add_cv<typename tuple_element<__i, _Tp>::type>::type type; + }; + /// Finds the size of a given tuple type. template<typename _Tp> struct tuple_size; - /// class tuple_size - template<typename... _Elements> - struct tuple_size<tuple<_Elements...> > - { - static const std::size_t value = sizeof...(_Elements); - }; + template<typename _Tp> + struct tuple_size<const _Tp> + : public integral_constant< + typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, + tuple_size<_Tp>::value> { }; + template<typename _Tp> + struct tuple_size<volatile _Tp> + : public integral_constant< + typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, + tuple_size<_Tp>::value> { }; + + template<typename _Tp> + struct tuple_size<const volatile _Tp> + : public integral_constant< + typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, + tuple_size<_Tp>::value> { }; + + /// class tuple_size template<typename... _Elements> - const std::size_t tuple_size<tuple<_Elements...> >::value; + struct tuple_size<tuple<_Elements...>> + : public integral_constant<std::size_t, sizeof...(_Elements)> { }; template<std::size_t __i, typename _Head, typename... _Tail> inline typename __add_ref<_Head>::type - __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) + __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return __t._M_head(); } template<std::size_t __i, typename _Head, typename... _Tail> inline typename __add_c_ref<_Head>::type - __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) + __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { 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. + // Return a reference (const reference, rvalue reference) to the ith element + // of a tuple. Any const or non-const ref elements are returned with their + // original type. template<std::size_t __i, typename... _Elements> inline typename __add_ref< - typename tuple_element<__i, tuple<_Elements...> >::type + typename tuple_element<__i, tuple<_Elements...>>::type >::type - get(tuple<_Elements...>& __t) + get(tuple<_Elements...>& __t) noexcept { return __get_helper<__i>(__t); } template<std::size_t __i, typename... _Elements> inline typename __add_c_ref< - typename tuple_element<__i, tuple<_Elements...> >::type + typename tuple_element<__i, tuple<_Elements...>>::type >::type - get(const tuple<_Elements...>& __t) + get(const tuple<_Elements...>& __t) noexcept { return __get_helper<__i>(__t); } + template<std::size_t __i, typename... _Elements> + inline typename __add_r_ref< + typename tuple_element<__i, tuple<_Elements...>>::type + >::type + get(tuple<_Elements...>&& __t) noexcept + { return std::forward<typename tuple_element<__i, + tuple<_Elements...>>::type&&>(get<__i>(__t)); } + // This class helps construct the various comparison operations on tuples template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j, typename _Tp, typename _Up> @@ -628,7 +678,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _Elements> inline tuple<_Elements&&...> - forward_as_tuple(_Elements&&... __args) + forward_as_tuple(_Elements&&... __args) noexcept { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } template<std::size_t...> struct __index_holder { }; @@ -737,12 +787,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _Elements> inline tuple<_Elements&...> - tie(_Elements&... __args) + tie(_Elements&... __args) noexcept { return tuple<_Elements&...>(__args...); } template<typename... _Elements> inline void swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) + noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } // A class (and instance) which can be used in 'tie' when an element |