diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2015-06-05 17:44:26 +0300 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2015-06-05 15:44:26 +0100 |
commit | ddb63209a8dc059a7b2a137d7a1859222bb43dd6 (patch) | |
tree | 3ceea62da88739a862bf476777be8b79b37f00a6 /libstdc++-v3 | |
parent | ac59f9beec4e2f44bd3c04eb8f4fb9432feaea40 (diff) | |
download | gcc-ddb63209a8dc059a7b2a137d7a1859222bb43dd6.zip gcc-ddb63209a8dc059a7b2a137d7a1859222bb43dd6.tar.gz gcc-ddb63209a8dc059a7b2a137d7a1859222bb43dd6.tar.bz2 |
Add __is_nothrow_swappable and take it into use.
2015-06-04 Ville Voutilainen <ville.voutilainen@gmail.com>
Add __is_nothrow_swappable and take it into use.
* include/bits/algorithmfwd.h (swap): Only declare for C++98 mode.
* include/bits/move.h (swap): Add constraints in C++11 and later.
* include/bits/stl_pair.h (swap): Use __is_nothrow_swappable
for the free swap function for pair.
* include/bits/stl_queue.h (swap): Use __is_nothrow_swappable
for the free swap functions for queue and priority_queue.
* include/bits/stl_stack.h (swap): Use __is_nothrow_swappable
for the free swap function for stack.
* include/debug/array (swap): Use __is_nothrow_swappable
for the free swap function for array.
* include/profile/array (swap): Likewise.
* include/std/array (swap): Likewise.
* include/std/tuple (_Tuple_impl::_M_swap): Use __is_nothrow_swappable.
* include/std/type_traits (__is_swappable_impl::__is_swappable,
__is_nothrow_swappable_impl, __is_nothrow_swappable): New.
* testsuite/20_util/is_nothrow_swappable/requirements/
explicit_instantiation.cc: New.
* testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc:
New.
* testsuite/20_util/is_nothrow_swappable/value.cc: New.
From-SVN: r224153
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 24 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/algorithmfwd.h | 21 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/move.h | 17 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_pair.h | 4 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_queue.h | 5 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/stl_stack.h | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/debug/array | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/profile/array | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/std/array | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/std/tuple | 7 | ||||
-rw-r--r-- | libstdc++-v3/include/std/type_traits | 46 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc | 27 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc | 32 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/is_nothrow_swappable/value.cc | 72 |
14 files changed, 234 insertions, 29 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 89e0fcf..4efd866 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,27 @@ +2015-06-04 Ville Voutilainen <ville.voutilainen@gmail.com> + + Add __is_nothrow_swappable and take it into use. + * include/bits/algorithmfwd.h (swap): Only declare for C++98 mode. + * include/bits/move.h (swap): Add constraints in C++11 and later. + * include/bits/stl_pair.h (swap): Use __is_nothrow_swappable + for the free swap function for pair. + * include/bits/stl_queue.h (swap): Use __is_nothrow_swappable + for the free swap functions for queue and priority_queue. + * include/bits/stl_stack.h (swap): Use __is_nothrow_swappable + for the free swap function for stack. + * include/debug/array (swap): Use __is_nothrow_swappable + for the free swap function for array. + * include/profile/array (swap): Likewise. + * include/std/array (swap): Likewise. + * include/std/tuple (_Tuple_impl::_M_swap): Use __is_nothrow_swappable. + * include/std/type_traits (__is_swappable_impl::__is_swappable, + __is_nothrow_swappable_impl, __is_nothrow_swappable): New. + * testsuite/20_util/is_nothrow_swappable/requirements/ + explicit_instantiation.cc: New. + * testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc: + New. + * testsuite/20_util/is_nothrow_swappable/value.cc: New. + 2015-06-03 François Dumont fdumont@gcc.gnu.org> * testsuite/23_containers/list/61347.cc: Add dg-require-normal-mode. diff --git a/libstdc++-v3/include/bits/algorithmfwd.h b/libstdc++-v3/include/bits/algorithmfwd.h index 1dfc4ad..c972f33 100644 --- a/libstdc++-v3/include/bits/algorithmfwd.h +++ b/libstdc++-v3/include/bits/algorithmfwd.h @@ -566,22 +566,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _BIter stable_partition(_BIter, _BIter, _Predicate); - template<typename _Tp> - void - swap(_Tp&, _Tp&) -#if __cplusplus >= 201103L - noexcept(__and_<is_nothrow_move_constructible<_Tp>, - is_nothrow_move_assignable<_Tp>>::value) -#endif - ; +#if __cplusplus < 201103L + // For C++11 swap() is declared in <type_traits>. template<typename _Tp, size_t _Nm> - void - swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) -#if __cplusplus >= 201103L - noexcept(noexcept(swap(*__a, *__b))) + inline void + swap(_Tp& __a, _Tp& __b); + + template<typename _Tp, size_t _Nm> + inline void + swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]); #endif - ; template<typename _FIter1, typename _FIter2> _FIter2 diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h index 1dfd667..88c4f7b 100644 --- a/libstdc++-v3/include/bits/move.h +++ b/libstdc++-v3/include/bits/move.h @@ -172,11 +172,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @return Nothing. */ template<typename _Tp> - inline void - swap(_Tp& __a, _Tp& __b) + inline #if __cplusplus >= 201103L + typename enable_if<__and_<is_move_constructible<_Tp>, + is_move_assignable<_Tp>>::value>::type + swap(_Tp& __a, _Tp& __b) noexcept(__and_<is_nothrow_move_constructible<_Tp>, is_nothrow_move_assignable<_Tp>>::value) +#else + void + swap(_Tp& __a, _Tp& __b) #endif { // concept requirements @@ -191,10 +196,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // DR 809. std::swap should be overloaded for array types. /// Swap the contents of two arrays. template<typename _Tp, size_t _Nm> - inline void - swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) + inline #if __cplusplus >= 201103L + typename enable_if<__is_swappable_impl::__is_swappable<_Tp>::value>::type + swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) noexcept(noexcept(swap(*__a, *__b))) +#else + void + swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) #endif { for (size_t __n = 0; __n < _Nm; ++__n) diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h index 3daeb60..490b005 100644 --- a/libstdc++-v3/include/bits/stl_pair.h +++ b/libstdc++-v3/include/bits/stl_pair.h @@ -192,8 +192,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void swap(pair& __p) - noexcept(noexcept(swap(first, __p.first)) - && noexcept(swap(second, __p.second))) + noexcept(__is_nothrow_swappable<_T1>::value + && __is_nothrow_swappable<_T2>::value) { using std::swap; swap(first, __p.first); diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h index 48e1ee7..5f8e6fb 100644 --- a/libstdc++-v3/include/bits/stl_queue.h +++ b/libstdc++-v3/include/bits/stl_queue.h @@ -247,7 +247,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L void swap(queue& __q) - noexcept(noexcept(swap(c, __q.c))) + noexcept(__is_nothrow_swappable<_Tp>::value) { using std::swap; swap(c, __q.c); @@ -541,7 +541,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L void swap(priority_queue& __pq) - noexcept(noexcept(swap(c, __pq.c)) && noexcept(swap(comp, __pq.comp))) + noexcept(__is_nothrow_swappable<_Tp>::value + && __is_nothrow_swappable<_Compare>::value) { using std::swap; swap(c, __pq.c); diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h index 3ff307f..0ed212e 100644 --- a/libstdc++-v3/include/bits/stl_stack.h +++ b/libstdc++-v3/include/bits/stl_stack.h @@ -221,7 +221,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L void swap(stack& __s) - noexcept(noexcept(swap(c, __s.c))) + noexcept(__is_nothrow_swappable<_Tp>::value) { using std::swap; swap(c, __s.c); diff --git a/libstdc++-v3/include/debug/array b/libstdc++-v3/include/debug/array index 7bb74c1..34e6281 100644 --- a/libstdc++-v3/include/debug/array +++ b/libstdc++-v3/include/debug/array @@ -84,7 +84,7 @@ namespace __debug void swap(array& __other) - noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))) + noexcept(__is_nothrow_swappable<_Tp>::value) { std::swap_ranges(begin(), end(), __other.begin()); } // Iterators. diff --git a/libstdc++-v3/include/profile/array b/libstdc++-v3/include/profile/array index 5198bb3..434ca96 100644 --- a/libstdc++-v3/include/profile/array +++ b/libstdc++-v3/include/profile/array @@ -63,7 +63,7 @@ namespace __profile void swap(array& __other) - noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))) + noexcept(__is_nothrow_swappable<_Tp>::value) { std::swap_ranges(begin(), end(), __other.begin()); } // Iterators. diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 24be44f..40fbd46 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -113,7 +113,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void swap(array& __other) - noexcept(noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))) + noexcept(__is_nothrow_swappable<_Tp>::value) { std::swap_ranges(begin(), end(), __other.begin()); } // Iterators. diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index ad132bd..ccea02b 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -324,9 +324,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION protected: void _M_swap(_Tuple_impl& __in) - noexcept(noexcept(swap(std::declval<_Head&>(), - std::declval<_Head&>())) - && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) + noexcept(__is_nothrow_swappable<_Head>::value + && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) { using std::swap; swap(_M_head(*this), _M_head(__in)); @@ -451,7 +450,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION protected: void _M_swap(_Tuple_impl& __in) - noexcept(noexcept(swap(std::declval<_Head&>(), std::declval<_Head&>()))) + noexcept(__is_nothrow_swappable<_Head>::value) { using std::swap; swap(_M_head(*this), _M_head(__in)); diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index b8ec61f..2eae61b 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -2427,6 +2427,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : true_type \ { }; + + namespace __is_swappable_impl { + template <typename _Tp, typename=void> + struct __is_swappable : public false_type + { }; + } + + template<typename _Tp> + inline + typename enable_if<__and_<is_move_constructible<_Tp>, + is_move_assignable<_Tp>>::value>::type + swap(_Tp&, _Tp&) + noexcept(__and_<is_nothrow_move_constructible<_Tp>, + is_nothrow_move_assignable<_Tp>>::value); + + template<typename _Tp, size_t _Nm> + inline + typename enable_if<__is_swappable_impl::__is_swappable<_Tp>::value>::type + swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) + noexcept(noexcept(swap(*__a, *__b))); + + namespace __is_swappable_impl { + using std::swap; + + template <typename _Tp> + struct __is_swappable<_Tp, __void_t<decltype(swap(declval<_Tp&>(), + declval<_Tp&>()))>> + : public true_type + { }; + } + + template <bool, typename _Tp> + struct __is_nothrow_swappable_impl + : public __bool_constant<noexcept(swap(declval<_Tp&>(), declval<_Tp&>()))> + { }; + + template <typename _Tp> + struct __is_nothrow_swappable_impl<false, _Tp> : public false_type + { }; + + template <typename _Tp> + struct __is_nothrow_swappable + : public __is_nothrow_swappable_impl< + __is_swappable_impl::__is_swappable<_Tp>::value, _Tp> + { }; + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc new file mode 100644 index 0000000..93fa94b --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc @@ -0,0 +1,27 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2015 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 +// <http://www.gnu.org/licenses/>. + +#include <type_traits> + +namespace std +{ + typedef short test_type; + template struct std::__is_nothrow_swappable<test_type>; +} diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc new file mode 100644 index 0000000..2372349 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc @@ -0,0 +1,32 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2015 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 +// <http://www.gnu.org/licenses/>. + +#include <type_traits> + + +void test01() +{ + // Check for required typedefs + typedef std::__is_nothrow_swappable<int> test_type; + typedef test_type::value_type value_type; + typedef test_type::type type; + typedef test_type::type::value_type type_value_type; + typedef test_type::type::type type_type; +} diff --git a/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/value.cc b/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/value.cc new file mode 100644 index 0000000..bc778b5 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_nothrow_swappable/value.cc @@ -0,0 +1,72 @@ +// { dg-options "-std=gnu++11" } +// { dg-do compile } + +// Copyright (C) 2015 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 +// <http://www.gnu.org/licenses/>. + +#include <type_traits> +#include <testsuite_tr1.h> +#include <utility> +#include <array> +#include <tuple> +#include <queue> +#include <stack> + +namespace funny { + struct F {}; + void swap(F&, F&) = delete; +} +void test01() +{ + using std::__is_nothrow_swappable; + using std::__is_swappable_impl::__is_swappable; + using namespace __gnu_test; + // Positive tests. + static_assert(test_property<__is_swappable, int>(true), ""); + static_assert(test_property<__is_nothrow_swappable, int>(true), ""); + static_assert(test_property<__is_nothrow_swappable, int[1]>(true), ""); + static_assert(test_property<__is_nothrow_swappable, + std::pair<int, int>>(true), ""); + static_assert(test_property<__is_nothrow_swappable, + std::tuple<int>>(true), ""); + static_assert(test_property<__is_nothrow_swappable, + std::array<int, 1>>(true), ""); + static_assert(test_property<__is_nothrow_swappable, + std::queue<int>>(true), ""); + static_assert(test_property<__is_nothrow_swappable, + std::priority_queue<int>>(true), ""); + static_assert(test_property<__is_nothrow_swappable, + std::stack<int>>(true), ""); + // Negative tests. + static_assert(test_property<__is_swappable, construct::DelCopy>(false), ""); + static_assert(test_property<__is_swappable, funny::F>(false), ""); + static_assert(test_property<__is_swappable, funny::F[1]>(false), ""); + static_assert(test_property<__is_nothrow_swappable, + ThrowCopyConsClass>(false), ""); + static_assert(test_property<__is_nothrow_swappable, + std::pair<ThrowCopyConsClass, ThrowCopyConsClass>>(false), ""); + static_assert(test_property<__is_nothrow_swappable, + std::tuple<ThrowCopyConsClass>>(false), ""); + static_assert(test_property<__is_nothrow_swappable, + std::array<ThrowCopyConsClass, 1>>(false), ""); + static_assert(test_property<__is_nothrow_swappable, + std::queue<ThrowCopyConsClass>>(false), ""); + static_assert(test_property<__is_nothrow_swappable, + std::priority_queue<ThrowCopyConsClass>>(false), ""); + static_assert(test_property<__is_nothrow_swappable, + std::stack<ThrowCopyConsClass>>(false), ""); +} |