From: Ville Voutilainen <ville.voutilainen@gmail.com>
To: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
libstdc++@gcc.gnu.org
Subject: [libstdc++ PATCH] Implement __is_nothrow_swappable and use it
Date: Fri, 01 May 2015 09:47:00 -0000 [thread overview]
Message-ID: <CAFk2RUbHSNQjhhR5YKnVnNcBX3mYFZouXDnrzmnuFgAe+unw4A@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 2150 bytes --]
This patch partially solves the problem described in N4426, which is
basically LWG
issue 2456, which in turn is caused by CWG DR 1330. Some remarks:
- the __is_swappable and __is_nothrow_swappable are at this time not
meant to be general traits, they make the shortcut of automatically transforming
their template parameter into a reference, which the truly general trait
as described in N4426 wouldn't do.
- swap is now constrained..
- ..which means that everything from bits/move.h moves to type_traits since
swap now needs type_traits. type_traits becomes ok to include in pre-c++14
modes, but only enables the parts that work in pre-c++14 modes.
- this patch does _not_ yet implement N4426.
Tested on Linux-x64.
2015-05-01 Ville Voutilainen <ville.voutilainen@gmail.com>
Add __is_nothrow_swappable and take it into use.
* libstdc++-v3/include/bits/algorithmfwd.h: Add constraints to the
forward-declaration of swap.
* include/bits/move.h: Move everything in it to..
* include/type_traits: ..here.
* include/type_traits (__swappable_impl::__swappable,
__is_nothrow_swappable_impl, __is_nothrow_swappable): New.
* 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 (_M_swap): Use __is_nothrow_swappable.
* testsuite/20_util/forward/c_neg.cc: Adjust.
* testsuite/20_util/forward/f_neg.cc: Likewise.
* testsuite/20_util/headers/type_traits/std_c++0x_neg.cc: Remove.
* testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc:
New.
* testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc: Likewise.
* testsuite/20_util/is_nothrow_swappable/value.cc: Likewise.
[-- Attachment #2: is_nothrow_swappable.diff --]
[-- Type: text/plain, Size: 25602 bytes --]
diff --git a/libstdc++-v3/include/bits/algorithmfwd.h b/libstdc++-v3/include/bits/algorithmfwd.h
index 1dfc4ad..0e37307 100644
--- a/libstdc++-v3/include/bits/algorithmfwd.h
+++ b/libstdc++-v3/include/bits/algorithmfwd.h
@@ -567,7 +567,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
stable_partition(_BIter, _BIter, _Predicate);
template<typename _Tp>
- void
+#if __cplusplus >= 201103L
+ typename enable_if<__and_<is_move_constructible<_Tp>,
+ is_move_assignable<_Tp>>::value>::type
+#else
+ void
+#endif
swap(_Tp&, _Tp&)
#if __cplusplus >= 201103L
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
@@ -576,7 +581,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
;
template<typename _Tp, size_t _Nm>
+#if __cplusplus >= 201103L
+ typename enable_if<__and_<is_move_constructible<_Tp>,
+ is_move_assignable<_Tp>>::value>::type
+#else
void
+#endif
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
#if __cplusplus >= 201103L
noexcept(noexcept(swap(*__a, *__b)))
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 1dfd667..96e2e51 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -30,179 +30,7 @@
#ifndef _MOVE_H
#define _MOVE_H 1
-#include <bits/c++config.h>
-#include <bits/concept_check.h>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- // Used, in C++03 mode too, by allocators, etc.
- /**
- * @brief Same as C++11 std::addressof
- * @ingroup utilities
- */
- template<typename _Tp>
- inline _Tp*
- __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
- {
- return reinterpret_cast<_Tp*>
- (&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
- }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
-
-#if __cplusplus >= 201103L
#include <type_traits> // Brings in std::declval too.
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- /**
- * @addtogroup utilities
- * @{
- */
-
- /**
- * @brief Forward an lvalue.
- * @return The parameter cast to the specified type.
- *
- * This function is used to implement "perfect forwarding".
- */
- template<typename _Tp>
- constexpr _Tp&&
- forward(typename std::remove_reference<_Tp>::type& __t) noexcept
- { return static_cast<_Tp&&>(__t); }
-
- /**
- * @brief Forward an rvalue.
- * @return The parameter cast to the specified type.
- *
- * This function is used to implement "perfect forwarding".
- */
- template<typename _Tp>
- constexpr _Tp&&
- forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
- {
- static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
- " substituting _Tp is an lvalue reference type");
- return static_cast<_Tp&&>(__t);
- }
-
- /**
- * @brief Convert a value to an rvalue.
- * @param __t A thing of arbitrary type.
- * @return The parameter cast to an rvalue-reference to allow moving it.
- */
- template<typename _Tp>
- constexpr typename std::remove_reference<_Tp>::type&&
- move(_Tp&& __t) noexcept
- { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
-
-
- template<typename _Tp>
- struct __move_if_noexcept_cond
- : public __and_<__not_<is_nothrow_move_constructible<_Tp>>,
- is_copy_constructible<_Tp>>::type { };
-
- /**
- * @brief Conditionally convert a value to an rvalue.
- * @param __x A thing of arbitrary type.
- * @return The parameter, possibly cast to an rvalue-reference.
- *
- * Same as std::move unless the type's move constructor could throw and the
- * type is copyable, in which case an lvalue-reference is returned instead.
- */
- template<typename _Tp>
- constexpr typename
- conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
- move_if_noexcept(_Tp& __x) noexcept
- { return std::move(__x); }
-
- // declval, from type_traits.
-
- /**
- * @brief Returns the actual address of the object or function
- * referenced by r, even in the presence of an overloaded
- * operator&.
- * @param __r Reference to an object or function.
- * @return The actual address.
- */
- template<typename _Tp>
- inline _Tp*
- addressof(_Tp& __r) noexcept
- { return std::__addressof(__r); }
-
- // C++11 version of std::exchange for internal use.
- template <typename _Tp, typename _Up = _Tp>
- inline _Tp
- __exchange(_Tp& __obj, _Up&& __new_val)
- {
- _Tp __old_val = std::move(__obj);
- __obj = std::forward<_Up>(__new_val);
- return __old_val;
- }
-
- /// @} group utilities
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
-
-#define _GLIBCXX_MOVE(__val) std::move(__val)
-#define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val)
-#else
-#define _GLIBCXX_MOVE(__val) (__val)
-#define _GLIBCXX_FORWARD(_Tp, __val) (__val)
-#endif
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- /**
- * @addtogroup utilities
- * @{
- */
-
- /**
- * @brief Swaps two values.
- * @param __a A thing of arbitrary type.
- * @param __b Another thing of arbitrary type.
- * @return Nothing.
- */
- template<typename _Tp>
- inline void
- swap(_Tp& __a, _Tp& __b)
-#if __cplusplus >= 201103L
- noexcept(__and_<is_nothrow_move_constructible<_Tp>,
- is_nothrow_move_assignable<_Tp>>::value)
-#endif
- {
- // concept requirements
- __glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
-
- _Tp __tmp = _GLIBCXX_MOVE(__a);
- __a = _GLIBCXX_MOVE(__b);
- __b = _GLIBCXX_MOVE(__tmp);
- }
-
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 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])
-#if __cplusplus >= 201103L
- noexcept(noexcept(swap(*__a, *__b)))
-#endif
- {
- for (size_t __n = 0; __n < _Nm; ++__n)
- swap(__a[__n], __b[__n]);
- }
-
- /// @} group utilities
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
#endif /* _MOVE_H */
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 31d146e..9bd1f3b 100644
--- a/libstdc++-v3/include/debug/array
+++ b/libstdc++-v3/include/debug/array
@@ -83,7 +83,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 a90e396..4c406d2 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 429506b..72d4649 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -105,7 +105,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 e500a76..5cd6d03 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 03e198a..ea35bc1 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -31,12 +31,12 @@
#pragma GCC system_header
+#include <bits/c++config.h>
+#include <bits/concept_check.h>
+
#if __cplusplus < 201103L
-# include <bits/c++0x_warning.h>
#else
-#include <bits/c++config.h>
-
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
# if defined (__UINT_LEAST16_TYPE__) && defined(__UINT_LEAST32_TYPE__)
namespace std
@@ -2427,4 +2427,221 @@ _GLIBCXX_END_NAMESPACE_VERSION
#endif // C++11
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ // Used, in C++03 mode too, by allocators, etc.
+ /**
+ * @brief Same as C++11 std::addressof
+ * @ingroup utilities
+ */
+ template<typename _Tp>
+ inline _Tp*
+ __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
+ {
+ return reinterpret_cast<_Tp*>
+ (&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+
+#if __cplusplus >= 201103L
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * @addtogroup utilities
+ * @{
+ */
+
+ /**
+ * @brief Forward an lvalue.
+ * @return The parameter cast to the specified type.
+ *
+ * This function is used to implement "perfect forwarding".
+ */
+ template<typename _Tp>
+ constexpr _Tp&&
+ forward(typename std::remove_reference<_Tp>::type& __t) noexcept
+ { return static_cast<_Tp&&>(__t); }
+
+ /**
+ * @brief Forward an rvalue.
+ * @return The parameter cast to the specified type.
+ *
+ * This function is used to implement "perfect forwarding".
+ */
+ template<typename _Tp>
+ constexpr _Tp&&
+ forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
+ {
+ static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
+ " substituting _Tp is an lvalue reference type");
+ return static_cast<_Tp&&>(__t);
+ }
+
+ /**
+ * @brief Convert a value to an rvalue.
+ * @param __t A thing of arbitrary type.
+ * @return The parameter cast to an rvalue-reference to allow moving it.
+ */
+ template<typename _Tp>
+ constexpr typename std::remove_reference<_Tp>::type&&
+ move(_Tp&& __t) noexcept
+ { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
+
+
+ template<typename _Tp>
+ struct __move_if_noexcept_cond
+ : public __and_<__not_<is_nothrow_move_constructible<_Tp>>,
+ is_copy_constructible<_Tp>>::type { };
+
+ /**
+ * @brief Conditionally convert a value to an rvalue.
+ * @param __x A thing of arbitrary type.
+ * @return The parameter, possibly cast to an rvalue-reference.
+ *
+ * Same as std::move unless the type's move constructor could throw and the
+ * type is copyable, in which case an lvalue-reference is returned instead.
+ */
+ template<typename _Tp>
+ constexpr typename
+ conditional<__move_if_noexcept_cond<_Tp>::value, const _Tp&, _Tp&&>::type
+ move_if_noexcept(_Tp& __x) noexcept
+ { return std::move(__x); }
+
+ // declval, from type_traits.
+
+ /**
+ * @brief Returns the actual address of the object or function
+ * referenced by r, even in the presence of an overloaded
+ * operator&.
+ * @param __r Reference to an object or function.
+ * @return The actual address.
+ */
+ template<typename _Tp>
+ inline _Tp*
+ addressof(_Tp& __r) noexcept
+ { return std::__addressof(__r); }
+
+ // C++11 version of std::exchange for internal use.
+ template <typename _Tp, typename _Up = _Tp>
+ inline _Tp
+ __exchange(_Tp& __obj, _Up&& __new_val)
+ {
+ _Tp __old_val = std::move(__obj);
+ __obj = std::forward<_Up>(__new_val);
+ return __old_val;
+ }
+
+ /// @} group utilities
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#define _GLIBCXX_MOVE(__val) std::move(__val)
+#define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val)
+#else
+#define _GLIBCXX_MOVE(__val) (__val)
+#define _GLIBCXX_FORWARD(_Tp, __val) (__val)
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * @addtogroup utilities
+ * @{
+ */
+
+ /**
+ * @brief Swaps two values.
+ * @param __a A thing of arbitrary type.
+ * @param __b Another thing of arbitrary type.
+ * @return Nothing.
+ */
+ template<typename _Tp>
+ inline
+#if __cplusplus >= 201103L
+ typename enable_if<__and_<is_move_constructible<_Tp>,
+ is_move_assignable<_Tp>>::value>::type
+#else
+ void
+#endif
+ swap(_Tp& __a, _Tp& __b)
+#if __cplusplus >= 201103L
+ noexcept(__and_<is_nothrow_move_constructible<_Tp>,
+ is_nothrow_move_assignable<_Tp>>::value)
+#endif
+ {
+ // concept requirements
+ __glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
+
+ _Tp __tmp = _GLIBCXX_MOVE(__a);
+ __a = _GLIBCXX_MOVE(__b);
+ __b = _GLIBCXX_MOVE(__tmp);
+ }
+
+#if __cplusplus >= 201103L
+ namespace __is_swappable_impl {
+ template <typename _Tp, typename=void>
+ struct __is_swappable : public false_type
+ { };
+ }
+#endif
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 809. std::swap should be overloaded for array types.
+ /// Swap the contents of two arrays.
+ template<typename _Tp, size_t _Nm>
+ inline
+#if __cplusplus >= 201103L
+ typename enable_if<__is_swappable_impl::__is_swappable<_Tp>::value>::type
+#else
+ void
+#endif
+ swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
+#if __cplusplus >= 201103L
+ noexcept(noexcept(swap(*__a, *__b)))
+#endif
+ {
+ for (size_t __n = 0; __n < _Nm; ++__n)
+ swap(__a[__n], __b[__n]);
+ }
+
+#if __cplusplus >= 201103L
+ 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>
+ { };
+#endif
+
+ /// @} group utilities
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
#endif // _GLIBCXX_TYPE_TRAITS
diff --git a/libstdc++-v3/testsuite/20_util/forward/c_neg.cc b/libstdc++-v3/testsuite/20_util/forward/c_neg.cc
index ca1c9c5..235338a 100644
--- a/libstdc++-v3/testsuite/20_util/forward/c_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/forward/c_neg.cc
@@ -18,7 +18,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-error "static assertion failed" "" { target *-*-* } 89 }
+// { dg-error "static assertion failed" "" { target *-*-* } 2482 }
#include <list>
diff --git a/libstdc++-v3/testsuite/20_util/forward/f_neg.cc b/libstdc++-v3/testsuite/20_util/forward/f_neg.cc
index 971168a..eada1b3 100644
--- a/libstdc++-v3/testsuite/20_util/forward/f_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/forward/f_neg.cc
@@ -18,7 +18,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-error "static assertion failed" "" { target *-*-* } 89 }
+// { dg-error "static assertion failed" "" { target *-*-* } 2482 }
#include <utility>
diff --git a/libstdc++-v3/testsuite/20_util/headers/type_traits/std_c++0x_neg.cc b/libstdc++-v3/testsuite/20_util/headers/type_traits/std_c++0x_neg.cc
deleted file mode 100644
index 8452b75..0000000
--- a/libstdc++-v3/testsuite/20_util/headers/type_traits/std_c++0x_neg.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// { dg-do compile }
-// { dg-options "-std=gnu++98" }
-
-// Copyright (C) 2007-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>
-
-// { dg-error "ISO C.. 2011" "" { target *-*-* } 32 }
-
-
-
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), "");
+}
next reply other threads:[~2015-05-01 9:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-01 9:47 Ville Voutilainen [this message]
2015-05-01 9:55 ` Ville Voutilainen
2015-06-05 14:58 ` Jonathan Wakely
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAFk2RUbHSNQjhhR5YKnVnNcBX3mYFZouXDnrzmnuFgAe+unw4A@mail.gmail.com \
--to=ville.voutilainen@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=libstdc++@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).