summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-05 14:44:26 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-05 14:44:26 +0000
commitb577348763f430df610bc31234afda83e6bfcd3b (patch)
tree3ceea62da88739a862bf476777be8b79b37f00a6
parentaa09f263efc6645e676390b92a79e3f88f3b712f (diff)
downloadgcc-b577348763f430df610bc31234afda83e6bfcd3b.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@224153 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog24
-rw-r--r--libstdc++-v3/include/bits/algorithmfwd.h21
-rw-r--r--libstdc++-v3/include/bits/move.h17
-rw-r--r--libstdc++-v3/include/bits/stl_pair.h4
-rw-r--r--libstdc++-v3/include/bits/stl_queue.h5
-rw-r--r--libstdc++-v3/include/bits/stl_stack.h2
-rw-r--r--libstdc++-v3/include/debug/array2
-rw-r--r--libstdc++-v3/include/profile/array2
-rw-r--r--libstdc++-v3/include/std/array2
-rw-r--r--libstdc++-v3/include/std/tuple7
-rw-r--r--libstdc++-v3/include/std/type_traits46
-rw-r--r--libstdc++-v3/testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc27
-rw-r--r--libstdc++-v3/testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc32
-rw-r--r--libstdc++-v3/testsuite/20_util/is_nothrow_swappable/value.cc72
14 files changed, 234 insertions, 29 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 89e0fcfae7b..4efd866729d 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 1dfc4ad7b15..c972f33c0f3 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 1dfd667a716..88c4f7b3e5c 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 3daeb60ab5c..490b00565a0 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 48e1ee79c6d..5f8e6fb9ab1 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 3ff307ff6ad..0ed212e4307 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 7bb74c17664..34e6281da5a 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 5198bb3af9c..434ca968d84 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 24be44f5b13..40fbd46c559 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 ad132bd8308..ccea02b4ffd 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 b8ec61f6892..2eae61bb8f4 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 00000000000..93fa94b5ea0
--- /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 00000000000..2372349b7dc
--- /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 00000000000..bc778b5bd7f
--- /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), "");
+}