From 1aa1114b634bbf707af735577fd311b713b88866 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Wed, 18 May 2011 00:12:58 +0000 Subject: [PATCH] tuple: Use noexcept where appropriate. 2011-05-17 Paolo Carlini * include/std/tuple: Use noexcept where appropriate. (tuple<>::swap): Rework implementation. (_Head_base<>::_M_swap_impl): Remove. (get(std::tuple<>&&)): Add. * testsuite/20_util/tuple/element_access/get2.cc: New. * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Adjust dg-error line number. From-SVN: r173838 --- libstdc++-v3/ChangeLog | 10 +++ libstdc++-v3/include/std/tuple | 85 +++++++++++-------- .../20_util/tuple/element_access/get2.cc | 41 +++++++++ .../20_util/weak_ptr/comparison/cmp_neg.cc | 2 +- 4 files changed, 101 insertions(+), 37 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/tuple/element_access/get2.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9b99d8b43f5..5b1284e6168 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2011-05-17 Paolo Carlini + + * include/std/tuple: Use noexcept where appropriate. + (tuple<>::swap): Rework implementation. + (_Head_base<>::_M_swap_impl): Remove. + (get(std::tuple<>&&)): Add. + * testsuite/20_util/tuple/element_access/get2.cc: New. + * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Adjust dg-error + line number. + 2011-05-16 Paolo Carlini * include/std/utility: Simplify the last commit, the whole diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index fb452aeb43e..066b3d0855c 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 + struct __add_r_ref + { typedef _Tp&& type; }; + + template + struct __add_r_ref<_Tp&> + { typedef _Tp& type; }; + template struct _Head_base; @@ -78,13 +87,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _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()); - } }; template @@ -103,13 +105,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _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_impl; }; @@ -130,9 +125,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template struct _Tuple_impl<_Idx> - { + { + template friend class _Tuple_impl; + protected: - void _M_swap_impl(_Tuple_impl&) { /* no-op */ } + void _M_swap(_Tuple_impl&) noexcept { /* no-op */ } }; /** @@ -145,6 +142,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public _Tuple_impl<_Idx + 1, _Tail...>, private _Head_base<_Idx, _Head, std::is_empty<_Head>::value> { + template friend class _Tuple_impl; + typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base; @@ -218,10 +217,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()); } }; @@ -300,14 +303,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 +364,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple& operator=(tuple&& __in) + // noexcept has to wait is_nothrow_move_assignable { static_cast<_Inherited&>(*this) = std::move(__in); return *this; @@ -392,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template tuple& - operator=(pair<_U1, _U2>&& __in) + operator=(pair<_U1, _U2>&& __in) noexcept { this->_M_head() = std::forward<_U1>(__in.first); this->_M_tail()._M_head() = std::forward<_U2>(__in.second); @@ -401,11 +406,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). @@ -473,7 +475,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void swap(tuple& __in) - { _Inherited::_M_swap_impl(__in); } + noexcept(noexcept(__in._M_swap(__in))) + { _Inherited::_M_swap(__in); } }; @@ -522,22 +525,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __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. + // 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 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 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 + inline typename __add_r_ref< + typename tuple_element<__i, tuple<_Elements...>>::type + >::type + get(tuple<_Elements...>&& __t) noexcept + { return std::forward>::type&&>(get<__i>(__t)); } + // This class helps construct the various comparison operations on tuples template @@ -628,7 +640,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template inline tuple<_Elements&&...> - forward_as_tuple(_Elements&&... __args) + forward_as_tuple(_Elements&&... __args) noexcept { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } template struct __index_holder { }; @@ -737,12 +749,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template inline tuple<_Elements&...> - tie(_Elements&... __args) + tie(_Elements&... __args) noexcept { return tuple<_Elements&...>(__args...); } template 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 diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get2.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/get2.cc new file mode 100644 index 00000000000..ccaedf402c8 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get2.cc @@ -0,0 +1,41 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// 2011-05-17 Paolo Carlini +// +// Copyright (C) 2011 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 3, 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 COPYING3. If not see +// . + +#include + +void test01() +{ + std::tuple t1; + + int&& t1one __attribute__((unused)) = std::get<0>(std::move(t1)); + + std::tuple t2; + + float&& t2one __attribute__((unused)) = std::get<0>(std::move(t2)); + int&& t2two __attribute__((unused)) = std::get<1>(std::move(t2)); + + std::tuple t3; + + short&& t3one __attribute__((unused)) = std::get<0>(std::move(t3)); + int&& t3two __attribute__((unused)) = std::get<1>(std::move(t3)); + double&& t3thr __attribute__((unused)) = std::get<2>(std::move(t3)); +} diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc index 919dbba74f5..5564b268570 100644 --- a/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc @@ -51,7 +51,7 @@ main() // { dg-warning "note" "" { target *-*-* } 485 } // { dg-warning "note" "" { target *-*-* } 479 } // { dg-warning "note" "" { target *-*-* } 469 } -// { dg-warning "note" "" { target *-*-* } 587 } +// { dg-warning "note" "" { target *-*-* } 599 } // { dg-warning "note" "" { target *-*-* } 1056 } // { dg-warning "note" "" { target *-*-* } 1050 } // { dg-warning "note" "" { target *-*-* } 342 } -- 2.30.2