public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch] Implement is_[nothrow_]swappable (p0185r1)
@ 2016-05-17 18:39 Daniel Krügler
  2016-05-23 11:50 ` Jonathan Wakely
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Krügler @ 2016-05-17 18:39 UTC (permalink / raw)
  To: libstdc++, gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 340 bytes --]

This is an implementation of the Standard is_swappable traits according to

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0185r1.html

During that work it has been found that std::array's member swap's exception
specification for zero-size arrays was incorrectly depending on the value_type
and that was fixed as well.

- Daniel

[-- Attachment #2: changelog.patch --]
[-- Type: application/octet-stream, Size: 2321 bytes --]

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 236335)
+++ ChangeLog	(working copy)
@@ -1,3 +1,44 @@
+2016-05-17  Daniel Kruegler  <daniel.kruegler@gmail.com>
+
+    Provide swappable traits (p0185r1)
+    * include/std/type_traits (is_swappable, is_nothrow_swappable,
+      is_swappable_with, is_nothrow_swappable_with, is_swappable_v, 
+      is_nothrow_swappable_v, is_swappable_with_v, 
+      is_nothrow_swappable_with_v): New.
+    * include/bits/stl_pair.h,
+      include/bits/stl_queue.h,
+      include/bits/stl_stack.h,
+      include/bits/unique_ptr.h,
+      include/std/tuple: Use it as of p0185r1.
+    * include/std/array: Use it and fix zero-size member swap
+    * include/bits/hashtable.h: Use __and_
+    * testsuite/20_util/is_nothrow_swappable/requirements/
+      explicit_instantiation.cc,
+      testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc,
+      testsuite/20_util/is_nothrow_swappable/value.cc,
+      testsuite/20_util/is_swappable/requirements/explicit_instantiation.cc,
+      testsuite/20_util/is_swappable/requirements/typedefs.cc,
+      testsuite/20_util/is_swappable/value.cc: Change test options to 
+      std=gnu++17.
+    * testsuite/20_util/is_nothrow_swappable/requirements/
+      explicit_instantiation_ext.cc,
+      testsuite/20_util/is_nothrow_swappable/requirements/typedefs_ext.cc,
+      testsuite/20_util/is_nothrow_swappable/value.h,
+      testsuite/20_util/is_nothrow_swappable/value_ext.cc,
+      testsuite/20_util/is_nothrow_swappable_with/requirements/
+      explicit_instantiation.cc,
+      testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc,
+      testsuite/20_util/is_nothrow_swappable_with/value.cc,
+      testsuite/20_util/is_swappable/requirements/
+      explicit_instantiation_ext.cc,
+      testsuite/20_util/is_swappable/requirements/typedefs_ext.cc,
+      testsuite/20_util/is_swappable/value.h,
+      testsuite/20_util/is_swappable/value_ext.cc,
+      testsuite/20_util/is_swappable_with/requirements/
+      explicit_instantiation.cc,
+      testsuite/20_util/is_swappable_with/requirements/typedefs.cc,
+      testsuite/20_util/is_swappable_with/value.cc: New.
+
 2016-05-13  Jonathan Wakely  <jwakely@redhat.com>
 
 	PR libstdc++/71073

[-- Attachment #3: is_swappable.patch --]
[-- Type: application/octet-stream, Size: 105968 bytes --]

Index: include/bits/hashtable.h
===================================================================
--- include/bits/hashtable.h	(revision 236301)
+++ include/bits/hashtable.h	(working copy)
@@ -475,8 +475,8 @@
 
       void
       swap(_Hashtable&)
-      noexcept(__is_nothrow_swappable<_H1>::value
-	       && __is_nothrow_swappable<_Equal>::value);
+      noexcept(__and_<__is_nothrow_swappable<_H1>,
+	                  __is_nothrow_swappable<_Equal>>::value);
 
       // Basic container operations
       iterator
@@ -1236,8 +1236,8 @@
     _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
 	       _H1, _H2, _Hash, _RehashPolicy, _Traits>::
     swap(_Hashtable& __x)
-    noexcept(__is_nothrow_swappable<_H1>::value
-	     && __is_nothrow_swappable<_Equal>::value)
+    noexcept(__and_<__is_nothrow_swappable<_H1>,
+	                __is_nothrow_swappable<_Equal>>::value)
     {
       // The only base class with member variables is hash_code_base.
       // We define _Hash_code_base::_M_swap because different
Index: include/bits/stl_pair.h
===================================================================
--- include/bits/stl_pair.h	(revision 236301)
+++ include/bits/stl_pair.h	(working copy)
@@ -341,8 +341,8 @@
 
       void
       swap(pair& __p)
-      noexcept(__is_nothrow_swappable<_T1>::value
-               && __is_nothrow_swappable<_T2>::value)
+      noexcept(__and_<__is_nothrow_swappable<_T1>,
+                      __is_nothrow_swappable<_T2>>::value)
       {
 	using std::swap;
 	swap(first, __p.first);
@@ -399,11 +399,18 @@
   // Note:  no std::swap overloads in C++03 mode, this has performance
   //        implications, see, eg, libstdc++/38466.
   template<typename _T1, typename _T2>
-    inline void
+    inline 
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+    // Constrained free swap overload, see p0185r1  
+    typename enable_if<__and_<__is_swappable<_T1>,
+                              __is_swappable<_T2>>::value>::type
+#else                      
+    void
+#endif
     swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
     noexcept(noexcept(__x.swap(__y)))
     { __x.swap(__y); }
-#endif
+#endif // __cplusplus >= 201103L
 
   /**
    *  @brief A convenience wrapper for creating a pair from two objects.
Index: include/bits/stl_queue.h
===================================================================
--- include/bits/stl_queue.h	(revision 236301)
+++ include/bits/stl_queue.h	(working copy)
@@ -274,12 +274,16 @@
 #if __cplusplus >= 201103L
       void
       swap(queue& __q)
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+      noexcept(__is_nothrow_swappable<_Sequence>::value)
+#else
       noexcept(__is_nothrow_swappable<_Tp>::value)
+#endif
       {
 	using std::swap;
 	swap(c, __q.c);
       }
-#endif
+#endif // __cplusplus >= 201103L
     };
 
   /**
@@ -342,7 +346,13 @@
 
 #if __cplusplus >= 201103L
   template<typename _Tp, typename _Seq>
-    inline void
+    inline 
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+    // Constrained free swap overload, see p0185r1  
+    typename enable_if<__is_swappable<_Seq>::value>::type
+#else                      
+    void
+#endif
     swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y)
     noexcept(noexcept(__x.swap(__y)))
     { __x.swap(__y); }
@@ -350,7 +360,7 @@
   template<typename _Tp, typename _Seq, typename _Alloc>
     struct uses_allocator<queue<_Tp, _Seq>, _Alloc>
     : public uses_allocator<_Seq, _Alloc>::type { };
-#endif
+#endif // __cplusplus >= 201103L
 
   /**
    *  @brief  A standard container automatically sorting its contents.
@@ -600,14 +610,20 @@
 #if __cplusplus >= 201103L
       void
       swap(priority_queue& __pq)
-      noexcept(__is_nothrow_swappable<_Tp>::value
-               && __is_nothrow_swappable<_Compare>::value)
+      noexcept(__and_<
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+                 __is_nothrow_swappable<_Sequence>,
+#else   
+                 __is_nothrow_swappable<_Tp>,
+#endif                 
+                 __is_nothrow_swappable<_Compare>
+               >::value)
       {
 	using std::swap;
 	swap(c, __pq.c);
 	swap(comp, __pq.comp);
       }
-#endif
+#endif // __cplusplus >= 201103L
     };
 
   // No equality/comparison operators are provided for priority_queue.
@@ -614,7 +630,14 @@
 
 #if __cplusplus >= 201103L
   template<typename _Tp, typename _Sequence, typename _Compare>
-    inline void
+    inline 
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+    // Constrained free swap overload, see p0185r1  
+    typename enable_if<__and_<__is_swappable<_Seq>,
+                              __is_swappable<_Compare>>::value>::type
+#else                      
+    void
+#endif
     swap(priority_queue<_Tp, _Sequence, _Compare>& __x,
 	 priority_queue<_Tp, _Sequence, _Compare>& __y)
     noexcept(noexcept(__x.swap(__y)))
@@ -624,7 +647,7 @@
 	   typename _Alloc>
     struct uses_allocator<priority_queue<_Tp, _Sequence, _Compare>, _Alloc>
     : public uses_allocator<_Sequence, _Alloc>::type { };
-#endif
+#endif // __cplusplus >= 201103L
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
Index: include/bits/stl_stack.h
===================================================================
--- include/bits/stl_stack.h	(revision 236301)
+++ include/bits/stl_stack.h	(working copy)
@@ -250,12 +250,16 @@
 #if __cplusplus >= 201103L
       void
       swap(stack& __s)
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+      noexcept(__is_nothrow_swappable<_Sequence>::value)
+#else
       noexcept(__is_nothrow_swappable<_Tp>::value)
+#endif
       {
 	using std::swap;
 	swap(c, __s.c);
       }
-#endif
+#endif // __cplusplus >= 201103L
     };
 
   /**
@@ -319,7 +323,13 @@
 
 #if __cplusplus >= 201103L
   template<typename _Tp, typename _Seq>
-    inline void
+    inline 
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+    // Constrained free swap overload, see p0185r1  
+    typename enable_if<__is_swappable<_Seq>::value>::type
+#else                      
+    void
+#endif
     swap(stack<_Tp, _Seq>& __x, stack<_Tp, _Seq>& __y)
     noexcept(noexcept(__x.swap(__y)))
     { __x.swap(__y); }
@@ -327,7 +337,7 @@
   template<typename _Tp, typename _Seq, typename _Alloc>
     struct uses_allocator<stack<_Tp, _Seq>, _Alloc>
     : public uses_allocator<_Seq, _Alloc>::type { };
-#endif
+#endif // __cplusplus >= 201103L
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
Index: include/bits/unique_ptr.h
===================================================================
--- include/bits/unique_ptr.h	(revision 236301)
+++ include/bits/unique_ptr.h	(working copy)
@@ -635,7 +635,13 @@
     };
 
   template<typename _Tp, typename _Dp>
-    inline void
+    inline 
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+    // Constrained free swap overload, see p0185r1  
+    typename enable_if<__is_swappable<_Dp>::value>::type
+#else                      
+    void
+#endif
     swap(unique_ptr<_Tp, _Dp>& __x,
 	 unique_ptr<_Tp, _Dp>& __y) noexcept
     { __x.swap(__y); }
Index: include/std/array
===================================================================
--- include/std/array	(revision 236301)
+++ include/std/array	(working copy)
@@ -48,6 +48,8 @@
     struct __array_traits
     {
       typedef _Tp _Type[_Nm];
+      typedef __is_swappable<_Tp> _Is_swappable;
+      typedef __is_nothrow_swappable<_Tp> _Is_nothrow_swappable;
 
       static constexpr _Tp&
       _S_ref(const _Type& __t, std::size_t __n) noexcept
@@ -62,6 +64,8 @@
    struct __array_traits<_Tp, 0>
    {
      struct _Type { };
+     typedef true_type _Is_swappable;
+     typedef true_type _Is_nothrow_swappable;
 
      static constexpr _Tp&
      _S_ref(const _Type&, std::size_t) noexcept
@@ -114,7 +118,7 @@
 
       void
       swap(array& __other)
-      noexcept(__is_nothrow_swappable<_Tp>::value)
+      noexcept(_AT_Type::_Is_nothrow_swappable::value)
       { std::swap_ranges(begin(), end(), __other.begin()); }
 
       // Iterators.
@@ -271,7 +275,15 @@
 
   // Specialized algorithms.
   template<typename _Tp, std::size_t _Nm>
-    inline void
+    inline 
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+    // Constrained free swap overload, see p0185r1  
+    typename enable_if<
+      _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value
+    >::type
+#else                      
+    void
+#endif
     swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
     noexcept(noexcept(__one.swap(__two)))
     { __one.swap(__two); }
Index: include/std/tuple
===================================================================
--- include/std/tuple	(revision 236301)
+++ include/std/tuple	(working copy)
@@ -1542,7 +1542,14 @@
 
   /// swap
   template<typename... _Elements>
-    inline void 
+    inline 
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+    // Constrained free swap overload, see p0185r1  
+    typename enable_if<__and_<__is_swappable<_Elements>...>::value
+      >::type
+#else                      
+    void
+#endif
     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
     noexcept(noexcept(__x.swap(__y)))
     { __x.swap(__y); }
Index: include/std/type_traits
===================================================================
--- include/std/type_traits	(revision 236301)
+++ include/std/type_traits	(working copy)
@@ -2631,7 +2631,7 @@
         static false_type __test(...);
     };
 
-  }
+  } // namespace __swappable_details
 
   template<typename _Tp>
     struct __is_swappable_impl
@@ -2657,6 +2657,112 @@
     : public __is_nothrow_swappable_impl<_Tp>::type
     { };
 
+#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
+#define __cpp_lib_is_swappable 201603
+  /// Metafunctions used for detecting swappable types: p0185r1
+  
+  /// is_swappable
+  template<typename _Tp>
+    struct is_swappable
+    : public __is_swappable_impl<_Tp>::type
+    { };
+
+  /// is_nothrow_swappable
+  template<typename _Tp>
+    struct is_nothrow_swappable
+    : public __is_nothrow_swappable_impl<_Tp>::type
+    { };
+
+  /// is_swappable_v
+  template<typename _Tp> 
+    constexpr bool is_swappable_v = is_swappable<_Tp>::value;
+    
+  /// is_nothrow_swappable_v
+  template<typename _Tp> 
+    constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value;
+    
+  namespace __swappable_with_details {
+    using std::swap;
+
+    struct __do_is_swappable_with_impl
+    {
+      template<typename _Tp, typename _Up, typename
+               = decltype(swap(std::declval<_Tp>(), std::declval<_Up>())),
+               typename
+               = decltype(swap(std::declval<_Up>(), std::declval<_Tp>()))>
+        static true_type __test(int);
+
+      template<typename, typename>
+        static false_type __test(...);
+    };
+
+    struct __do_is_nothrow_swappable_with_impl
+    {
+      template<typename _Tp, typename _Up>
+        static __bool_constant<
+          noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))
+          &&
+          noexcept(swap(std::declval<_Up>(), std::declval<_Tp>()))
+        > __test(int);
+
+      template<typename, typename>
+        static false_type __test(...);
+    };
+
+  } // namespace __swappable_with_details
+
+  template<typename _Tp, typename _Up>
+    struct __is_swappable_with_impl
+    : public __swappable_with_details::__do_is_swappable_with_impl
+    {
+      typedef decltype(__test<_Tp, _Up>(0)) type;
+    };
+
+  // Optimization for the homogenous lvalue case, not required:
+  template<typename _Tp>
+    struct __is_swappable_with_impl<_Tp&, _Tp&>
+    : public __swappable_details::__do_is_swappable_impl
+    {
+      typedef decltype(__test<_Tp&>(0)) type;
+    };
+
+  template<typename _Tp, typename _Up>
+    struct __is_nothrow_swappable_with_impl
+    : public __swappable_with_details::__do_is_nothrow_swappable_with_impl
+    {
+      typedef decltype(__test<_Tp, _Up>(0)) type;
+    };
+
+  // Optimization for the homogenous lvalue case, not required:
+  template<typename _Tp>
+    struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&>
+    : public __swappable_details::__do_is_nothrow_swappable_impl
+    {
+      typedef decltype(__test<_Tp&>(0)) type;
+    };
+
+  /// is_swappable_with
+  template<typename _Tp, typename _Up>
+    struct is_swappable_with
+    : public __is_swappable_with_impl<_Tp, _Up>::type
+    { };
+
+  /// is_nothrow_swappable_with
+  template<typename _Tp, typename _Up>
+    struct is_nothrow_swappable_with
+    : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type
+    { };
+
+  /// is_swappable_with_v
+  template<typename _Tp, typename _Up> 
+    constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value;
+    
+  /// is_nothrow_swappable_with_v
+  template<typename _Tp, typename _Up> 
+    constexpr bool is_nothrow_swappable_with_v =
+      is_nothrow_swappable_with<_Tp, _Up>::value;
+#endif
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
Index: testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc	(revision 236301)
+++ testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation.cc	(working copy)
@@ -1,4 +1,4 @@
-// { dg-options "-std=gnu++11" }
+// { dg-options "-std=gnu++17" }
 // { dg-do compile }
 
 // Copyright (C) 2015-2016 Free Software Foundation, Inc.
@@ -20,8 +20,14 @@
 
 #include <type_traits>
 
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_nothrow_swappable missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_nothrow_swappable has wrong value"
+#endif
+
 namespace std
 {
   typedef short test_type;
-  template struct std::__is_nothrow_swappable<test_type>;
+  template struct std::is_nothrow_swappable<test_type>;
 }
Index: testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc	(revision 236301)
+++ testsuite/20_util/is_nothrow_swappable/requirements/typedefs.cc	(working copy)
@@ -1,4 +1,4 @@
-// { dg-options "-std=gnu++11" }
+// { dg-options "-std=gnu++17" }
 // { dg-do compile }
 
 // Copyright (C) 2015-2016 Free Software Foundation, Inc.
@@ -20,11 +20,16 @@
 
 #include <type_traits>
 
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_nothrow_swappable missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_nothrow_swappable has wrong value"
+#endif
 
 void test01()
 {
   // Check for required typedefs
-  typedef std::__is_nothrow_swappable<int>          test_type;
+  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;
Index: testsuite/20_util/is_nothrow_swappable/value.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable/value.cc	(revision 236301)
+++ testsuite/20_util/is_nothrow_swappable/value.cc	(working copy)
@@ -1,4 +1,4 @@
-// { dg-options "-std=gnu++11" }
+// { dg-options "-std=gnu++17" }
 // { dg-do compile }
 
 // Copyright (C) 2015-2016 Free Software Foundation, Inc.
@@ -18,218 +18,5 @@
 // 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 swap(F(&)[5], F(&)[5]) noexcept;
-  void swap(F(&)[6], F(&)[6]);
-  struct A {};
-  void swap(A&, A&) noexcept(false);
-}
-namespace std {
-  template<>
-  void swap<funny::A>(funny::A&, funny::A&) noexcept
-  {
-  }
-
-  template<>
-  void swap<funny::A>(funny::A(&)[3], funny::A(&)[3]) noexcept(false)
-  {
-  }
-}
-namespace ns1 {
-  struct SwapThrow {};
-  void swap(SwapThrow&, SwapThrow&);
-  void swap(SwapThrow(&)[3], SwapThrow(&)[3]) noexcept;
-}
-
-namespace ns2 {
-  struct SwapThrow {
-    SwapThrow() noexcept = default;
-    SwapThrow(const SwapThrow&) noexcept(false);
-    SwapThrow& operator=(const SwapThrow&) noexcept(false);
-  };
-}
-
-namespace ns3 {
-  struct SwapNoThrow {
-    SwapNoThrow() noexcept = default;
-    SwapNoThrow(const SwapNoThrow&) noexcept(false);
-    SwapNoThrow& operator =(const SwapNoThrow&) noexcept(false);
-  };
-  void swap(SwapNoThrow&, SwapNoThrow&) noexcept;
-}
-
-namespace ns4 {
-  struct SwapNoThrow {};
-}
-
-namespace ns5 {
-  struct SwapThrow {
-    SwapThrow() noexcept = default;
-    SwapThrow(SwapThrow&&) noexcept;
-    SwapThrow& operator=(const SwapThrow&) noexcept(false);
-  };
-}
-void test01()
-{
-  using std::__is_nothrow_swappable;
-  using namespace __gnu_test;
-  // Positive tests.
-  static_assert(test_property<__is_nothrow_swappable, int>(true), "");
-  static_assert(test_property<__is_nothrow_swappable, bool>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    decltype(nullptr)>(true), "");
-  static_assert(test_property<__is_nothrow_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, int[1][2]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable, int[1][2][3]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable, funny::F[5]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable, EnumType>(true), "");
-  static_assert(test_property<__is_nothrow_swappable, PODType>(true), "");
-  static_assert(test_property<__is_nothrow_swappable, UnionType>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    construct::SE>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    construct::Empty>(true), "");
-  static_assert(test_property<__is_nothrow_swappable, void*>(true), "");
-  static_assert(test_property<__is_nothrow_swappable, void(*)()>(true), "");
-  static_assert(test_property<__is_nothrow_swappable, int const*>(true), "");
-  static_assert(test_property<__is_nothrow_swappable, ClassType*>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    int ClassType::*>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    void (ClassType::*)()>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    int (ClassType::*)() const volatile>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns1::SwapThrow[3]>(true), "");
-  static_assert(!noexcept(std::swap(std::declval<ns1::SwapThrow(&)[3]>(),
-                                    std::declval<ns1::SwapThrow(&)[3]>())),
-                                    "");
-  static_assert(test_property<__is_nothrow_swappable,
-        ns3::SwapNoThrow>(true), "");
-  static_assert(!noexcept(std::swap(std::declval<ns3::SwapNoThrow&>(),
-                                    std::declval<ns3::SwapNoThrow&>())), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        ns3::SwapNoThrow[1]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        ns3::SwapNoThrow[3]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        ns3::SwapNoThrow[2][3][4]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        ns4::SwapNoThrow>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        ns4::SwapNoThrow[1]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        ns4::SwapNoThrow[3]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        ns4::SwapNoThrow[2][3][4]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        std::pair<int, int>>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        std::pair<int, int>[1]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        std::pair<int, int>[1][2]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        std::tuple<int>>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        std::tuple<int>[1]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        std::tuple<int>[1][2]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        std::tuple<>>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        std::tuple<>[1]>(true), "");
-  static_assert(test_property<__is_nothrow_swappable,
-        std::tuple<>[1][2]>(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_nothrow_swappable, void>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, const void>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, void()>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    void() const>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    void() volatile>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    void() const volatile>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, const int>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, const bool>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    const int[1]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    const int[1][2]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    const int[1][2][3]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, int[]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, const int[]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, int[][1]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    const funny::F[5]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    construct::Abstract>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    construct::DelCopy>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, funny::F>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, funny::F[1]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    funny::F[1][2]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    funny::F[1][2][3]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, funny::F[6]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable, funny::A>(false), "");
-  static_assert(noexcept(std::swap(std::declval<funny::A&>(),
-                                   std::declval<funny::A&>())), "");
-  static_assert(test_property<__is_nothrow_swappable, funny::A[3]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns1::SwapThrow>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns1::SwapThrow[1]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns1::SwapThrow[3][2]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns1::SwapThrow[2][3][4]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns2::SwapThrow>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns2::SwapThrow[1]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns2::SwapThrow[2][3][4]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns5::SwapThrow>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns5::SwapThrow[1]>(false), "");
-  static_assert(test_property<__is_nothrow_swappable,
-    ns5::SwapThrow[2][3][4]>(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), "");
-}
+#define test_std_is_nothrow_swappable
+#include "./value.h"
Index: testsuite/20_util/is_swappable/requirements/explicit_instantiation.cc
===================================================================
--- testsuite/20_util/is_swappable/requirements/explicit_instantiation.cc	(revision 236301)
+++ testsuite/20_util/is_swappable/requirements/explicit_instantiation.cc	(working copy)
@@ -1,7 +1,7 @@
-// { dg-options "-std=gnu++11" }
+// { dg-options "-std=gnu++17" }
 // { dg-do compile }
 
-// Copyright (C) 2015 Free Software Foundation, Inc.
+// Copyright (C) 2015-2016 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
@@ -20,8 +20,14 @@
 
 #include <type_traits>
 
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_swappable missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_swappable has wrong value"
+#endif
+
 namespace std
 {
   typedef short test_type;
-  template struct std::__is_swappable<test_type>;
+  template struct std::is_swappable<test_type>;
 }
Index: testsuite/20_util/is_swappable/requirements/typedefs.cc
===================================================================
--- testsuite/20_util/is_swappable/requirements/typedefs.cc	(revision 236301)
+++ testsuite/20_util/is_swappable/requirements/typedefs.cc	(working copy)
@@ -1,7 +1,7 @@
-// { dg-options "-std=gnu++11" }
+// { dg-options "-std=gnu++17" }
 // { dg-do compile }
 
-// Copyright (C) 2015 Free Software Foundation, Inc.
+// Copyright (C) 2015-2016 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
@@ -20,10 +20,16 @@
 
 #include <type_traits>
 
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_swappable missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_swappable has wrong value"
+#endif
+
 void test01()
 {
   // Check for required typedefs
-  typedef std::__is_swappable<int>          test_type;
+  typedef std::is_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;
Index: testsuite/20_util/is_swappable/value.cc
===================================================================
--- testsuite/20_util/is_swappable/value.cc	(revision 236301)
+++ testsuite/20_util/is_swappable/value.cc	(working copy)
@@ -1,7 +1,7 @@
-// { dg-options "-std=gnu++11" }
+// { dg-options "-std=gnu++17" }
 // { dg-do compile }
 
-// Copyright (C) 2015 Free Software Foundation, Inc.
+// Copyright (C) 2015-2016 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
@@ -18,168 +18,5 @@
 // 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 swap(F(&)[5], F(&)[5]);
-
-  struct F2
-  {
-    friend void swap(F2&, F2&) = delete;
-  };
-
-  struct F3
-  {
-    friend void swap(F3&, F3) {}
-  };
-}
-void test01()
-{
-  using std::__is_swappable;
-  using namespace __gnu_test;
-  // Positive tests.
-  static_assert(test_property<__is_swappable, int>(true), "");
-  static_assert(test_property<__is_swappable, bool>(true), "");
-  static_assert(test_property<__is_swappable, decltype(nullptr)>(true), "");
-  static_assert(test_property<__is_swappable, int&>(true), "");
-  static_assert(test_property<__is_swappable, int&&>(true), "");
-  static_assert(test_property<__is_swappable, int[1]>(true), "");
-  static_assert(test_property<__is_swappable, int[1][2]>(true), "");
-  static_assert(test_property<__is_swappable, int[1][2][3]>(true), "");
-  static_assert(test_property<__is_swappable, int(&)[1]>(true), "");
-  static_assert(test_property<__is_swappable, funny::F[5]>(true), "");
-  static_assert(test_property<__is_swappable, funny::F3>(true), "");
-  static_assert(test_property<__is_swappable, funny::F3[1]>(true), "");
-  static_assert(test_property<__is_swappable, funny::F3[1][2]>(true), "");
-  static_assert(test_property<__is_swappable, funny::F3[1][2][3]>(true), "");
-  static_assert(test_property<__is_swappable,
-    ThrowCopyConsClass>(true), "");
-  static_assert(test_property<__is_swappable, EnumType>(true), "");
-  static_assert(test_property<__is_swappable, PODType>(true), "");
-  static_assert(test_property<__is_swappable, UnionType>(true), "");
-  static_assert(test_property<__is_swappable, construct::SE>(true), "");
-  static_assert(test_property<__is_swappable, construct::Empty>(true), "");
-  static_assert(test_property<__is_swappable, void*>(true), "");
-  static_assert(test_property<__is_swappable, int const*>(true), "");
-  static_assert(test_property<__is_swappable, ClassType*>(true), "");
-  static_assert(test_property<__is_swappable, int ClassType::*>(true), "");
-  static_assert(test_property<__is_swappable,
-    void (ClassType::*)()>(true), "");
-  static_assert(test_property<__is_swappable,
-    construct::Nontrivial>(true), "");
-  static_assert(test_property<__is_swappable, construct::Any>(true), "");
-  static_assert(test_property<__is_swappable, construct::nAny>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::pair<int, int>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::pair<int, int>[1]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::pair<int, int>[1][2]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::pair<int, int>[1][2][3]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::pair<construct::Nontrivial, construct::Nontrivial>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::tuple<int>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::tuple<int>[1]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::tuple<int>[1][2]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::tuple<int>[1][2][3]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::tuple<>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::tuple<>[1]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::tuple<>[1][2]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::tuple<>[1][2][3]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::tuple<construct::Nontrivial>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::array<int, 1>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::array<int, 1>[1]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::array<int, 1>[1][2]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::array<int, 1>[1][2][3]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::array<construct::Nontrivial, 1>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::queue<int>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::queue<int>[1]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::queue<int>[1][2]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::queue<int>[1][2][3]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::queue<construct::Nontrivial>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::priority_queue<int>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::priority_queue<int>[1]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::priority_queue<int>[1][2]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::priority_queue<int>[1][2][3]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::priority_queue<construct::Nontrivial>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::stack<int>>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::stack<int>[1]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::stack<int>[1][2]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::stack<int>[1][2][3]>(true), "");
-  static_assert(test_property<__is_swappable,
-		std::stack<construct::Nontrivial>>(true), "");
-  // Negative tests.
-  static_assert(test_property<__is_swappable, void>(false), "");
-  static_assert(test_property<__is_swappable, const void>(false), "");
-  static_assert(test_property<__is_swappable, void()>(false), "");
-  static_assert(test_property<__is_swappable, void() const>(false), "");
-  static_assert(test_property<__is_swappable, void() volatile>(false), "");
-  static_assert(test_property<__is_swappable,
-    void() const volatile>(false), "");
-  static_assert(test_property<__is_swappable, const int>(false), "");
-  static_assert(test_property<__is_swappable, const bool>(false), "");
-  static_assert(test_property<__is_swappable, int[]>(false), "");
-  static_assert(test_property<__is_swappable, const int[]>(false), "");
-  static_assert(test_property<__is_swappable, int[][1]>(false), "");
-  static_assert(test_property<__is_swappable, const int[1]>(false), "");
-  static_assert(test_property<__is_swappable, const int[1][2]>(false), "");
-  static_assert(test_property<__is_swappable, const int[1][2][3]>(false), "");
-  static_assert(test_property<__is_swappable, construct::DelCopy>(false), "");
-  static_assert(test_property<__is_swappable,
-    construct::Abstract>(false), "");
-  static_assert(test_property<__is_swappable,
-    construct::NontrivialUnion>(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_swappable, funny::F[1][2]>(false), "");
-  static_assert(test_property<__is_swappable, funny::F[1][2][3]>(false), "");
-  static_assert(test_property<__is_swappable, funny::F[4]>(false), "");
-  static_assert(test_property<__is_swappable, construct::DelCopy>(false), "");
-  static_assert(test_property<__is_swappable,
-     DeletedCopyAssignClass>(false), "");
-  static_assert(test_property<__is_swappable,
-     DeletedMoveAssignClass>(false), "");
-  static_assert(test_property<__is_swappable, funny::F2>(false), "");
-  static_assert(test_property<__is_swappable, funny::F2[1]>(false), "");
-  static_assert(test_property<__is_swappable, funny::F2[1][2]>(false), "");
-  static_assert(test_property<__is_swappable, funny::F2[1][2][3]>(false), "");
-  static_assert(test_property<__is_swappable, funny::F2[4]>(false), "");
-  static_assert(test_property<__is_swappable, funny::F2[5]>(false), "");
-}
+#define test_std_is_swappable
+#include "./value.h"
Index: testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation_ext.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation_ext.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable/requirements/explicit_instantiation_ext.cc	(working copy)
@@ -0,0 +1,27 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2015-2016 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>;
+}
Index: testsuite/20_util/is_nothrow_swappable/requirements/typedefs_ext.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable/requirements/typedefs_ext.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable/requirements/typedefs_ext.cc	(working copy)
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2015-2016 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;
+}
Index: testsuite/20_util/is_nothrow_swappable/value.h
===================================================================
--- testsuite/20_util/is_nothrow_swappable/value.h	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable/value.h	(working copy)
@@ -0,0 +1,297 @@
+// Copyright (C) 2015-2016 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>
+
+#if defined(test_std_is_nothrow_swappable)
+#  ifndef __cpp_lib_is_swappable
+#   error "Feature-test macro for is_nothrow_swappable missing"
+#  elif __cpp_lib_is_swappable != 201603
+#   error "Feature-test macro for is_nothrow_swappable has wrong value"
+#  endif
+// Test std::is_nothrow_swappable:
+template<class T>
+using is_nothrow_swappable = std::is_nothrow_swappable<T>; 
+#elif defined(test_std_is_nothrow_swappable_ext)
+// Test our __is_nothrow_swappable extension:
+template<class T>
+using is_nothrow_swappable = std::__is_nothrow_swappable<T>;
+#else
+# error "Either test_std_is_nothrow_swappable or " \
+        "test_std_is_nothrow_swappable_ext need to be defined"
+#endif
+
+namespace funny {
+  struct F {};
+  void swap(F&, F&) = delete;
+  void swap(F(&)[5], F(&)[5]) noexcept;
+  void swap(F(&)[6], F(&)[6]);
+  struct A {};
+  void swap(A&, A&) noexcept(false);
+}
+namespace std {
+  template<>
+  void swap<funny::A>(funny::A&, funny::A&) noexcept
+  {
+  }
+
+  template<>
+  void swap<funny::A>(funny::A(&)[3], funny::A(&)[3]) noexcept(false)
+  {
+  }
+}
+namespace ns1 {
+  struct SwapThrow {};
+  void swap(SwapThrow&, SwapThrow&);
+  void swap(SwapThrow(&)[3], SwapThrow(&)[3]) noexcept;
+}
+
+namespace ns2 {
+  struct SwapThrow {
+    SwapThrow() noexcept = default;
+    SwapThrow(const SwapThrow&) noexcept(false);
+    SwapThrow& operator=(const SwapThrow&) noexcept(false);
+  };
+}
+
+namespace ns3 {
+  struct SwapNoThrow {
+    SwapNoThrow() noexcept = default;
+    SwapNoThrow(const SwapNoThrow&) noexcept(false);
+    SwapNoThrow& operator =(const SwapNoThrow&) noexcept(false);
+  };
+  void swap(SwapNoThrow&, SwapNoThrow&) noexcept;
+}
+
+namespace ns4 {
+  struct SwapNoThrow {};
+}
+
+namespace ns5 {
+  struct SwapThrow {
+    SwapThrow() noexcept = default;
+    SwapThrow(SwapThrow&&) noexcept;
+    SwapThrow& operator=(const SwapThrow&) noexcept(false);
+  };
+}
+
+namespace comps {
+  struct CompareNoThrowCopyable 
+  { 
+    template<class T>
+    bool operator()(const T&, const T&) const
+    { return false; } 
+  };
+
+  struct CompareNonCopyable 
+  { 
+    CompareNonCopyable() = default;
+    CompareNonCopyable(const CompareNonCopyable&) = delete;
+    CompareNonCopyable& operator=(const CompareNonCopyable&) noexcept;
+    
+    template<class T>
+    bool operator()(const T&, const T&) const
+    { return false; }    
+  };
+
+  struct CompareThrowCopyable 
+  { 
+    CompareThrowCopyable() = default;
+    CompareThrowCopyable(const CompareThrowCopyable&) noexcept(false);
+    CompareThrowCopyable& operator=(const CompareThrowCopyable&);
+    
+    template<class T>
+    bool operator()(const T&, const T&) const
+    { return false; }    
+  };
+}
+
+void test01()
+{
+  using namespace __gnu_test;
+  // Positive tests.
+  static_assert(test_property<is_nothrow_swappable, int>(true), "");
+  static_assert(test_property<is_nothrow_swappable, bool>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+    decltype(nullptr)>(true), "");
+  static_assert(test_property<is_nothrow_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, int[1][2]>(true), "");
+  static_assert(test_property<is_nothrow_swappable, int[1][2][3]>(true), "");
+  static_assert(test_property<is_nothrow_swappable, funny::F[5]>(true), "");
+  static_assert(test_property<is_nothrow_swappable, EnumType>(true), "");
+  static_assert(test_property<is_nothrow_swappable, PODType>(true), "");
+  static_assert(test_property<is_nothrow_swappable, UnionType>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+    construct::SE>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+    construct::Empty>(true), "");
+  static_assert(test_property<is_nothrow_swappable, void*>(true), "");
+  static_assert(test_property<is_nothrow_swappable, void(*)()>(true), "");
+  static_assert(test_property<is_nothrow_swappable, int const*>(true), "");
+  static_assert(test_property<is_nothrow_swappable, ClassType*>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+    int ClassType::*>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+    void (ClassType::*)()>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+    int (ClassType::*)() const volatile>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns1::SwapThrow[3]>(true), "");
+  static_assert(!noexcept(std::swap(std::declval<ns1::SwapThrow(&)[3]>(),
+                                    std::declval<ns1::SwapThrow(&)[3]>())),
+                                    "");
+  static_assert(test_property<is_nothrow_swappable,
+        ns3::SwapNoThrow>(true), "");
+  static_assert(!noexcept(std::swap(std::declval<ns3::SwapNoThrow&>(),
+                                    std::declval<ns3::SwapNoThrow&>())), "");
+  static_assert(test_property<is_nothrow_swappable,
+        ns3::SwapNoThrow[1]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        ns3::SwapNoThrow[3]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        ns3::SwapNoThrow[2][3][4]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        ns4::SwapNoThrow>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        ns4::SwapNoThrow[1]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        ns4::SwapNoThrow[3]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        ns4::SwapNoThrow[2][3][4]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::pair<int, int>>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::pair<int, int>[1]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::pair<int, int>[1][2]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::tuple<int>>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::tuple<int>[1]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::tuple<int>[1][2]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::tuple<>>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::tuple<>[1]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::tuple<>[1][2]>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::array<int, 1>>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::array<int, 0>>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::array<construct::DelCopy, 0>>(true), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::array<ns1::SwapThrow, 0>>(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), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::priority_queue<int, std::vector<int>, 
+        comps::CompareNoThrowCopyable>>(true), "");
+
+  // Negative tests.
+  static_assert(test_property<is_nothrow_swappable, void>(false), "");
+  static_assert(test_property<is_nothrow_swappable, const void>(false), "");
+  static_assert(test_property<is_nothrow_swappable, void()>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    void() const>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    void() volatile>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    void() const volatile>(false), "");
+  static_assert(test_property<is_nothrow_swappable, const int>(false), "");
+  static_assert(test_property<is_nothrow_swappable, const bool>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    const int[1]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    const int[1][2]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    const int[1][2][3]>(false), "");
+  static_assert(test_property<is_nothrow_swappable, int[]>(false), "");
+  static_assert(test_property<is_nothrow_swappable, const int[]>(false), "");
+  static_assert(test_property<is_nothrow_swappable, int[][1]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    const funny::F[5]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    construct::Abstract>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    construct::DelCopy>(false), "");
+  static_assert(test_property<is_nothrow_swappable, funny::F>(false), "");
+  static_assert(test_property<is_nothrow_swappable, funny::F[1]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    funny::F[1][2]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    funny::F[1][2][3]>(false), "");
+  static_assert(test_property<is_nothrow_swappable, funny::F[6]>(false), "");
+  static_assert(test_property<is_nothrow_swappable, funny::A>(false), "");
+  static_assert(noexcept(std::swap(std::declval<funny::A&>(),
+                                   std::declval<funny::A&>())), "");
+  static_assert(test_property<is_nothrow_swappable, funny::A[3]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns1::SwapThrow>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns1::SwapThrow[1]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns1::SwapThrow[3][2]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns1::SwapThrow[2][3][4]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns2::SwapThrow>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns2::SwapThrow[1]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns2::SwapThrow[2][3][4]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns5::SwapThrow>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns5::SwapThrow[1]>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+    ns5::SwapThrow[2][3][4]>(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), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::priority_queue<int, std::vector<int>, 
+        comps::CompareNonCopyable>>(false), "");
+  static_assert(test_property<is_nothrow_swappable,
+        std::priority_queue<int, std::vector<int>, 
+        comps::CompareThrowCopyable>>(false), "");
+}
Index: testsuite/20_util/is_nothrow_swappable/value_ext.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable/value_ext.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable/value_ext.cc	(working copy)
@@ -0,0 +1,22 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2015-2016 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/>.
+
+#define test_std_is_nothrow_swappable_ext
+#include "./value.h"
Index: testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc	(working copy)
@@ -0,0 +1,36 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_nothrow_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_nothrow_swappable_with has wrong value"
+#endif
+
+namespace std
+{
+  typedef short test_type;
+  typedef double test_type_2;
+  template struct std::is_nothrow_swappable_with<test_type, test_type>;
+  template struct std::is_nothrow_swappable_with<test_type, test_type_2>;
+  template struct std::is_nothrow_swappable_with<test_type_2, test_type_2>;
+}
Index: testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc	(working copy)
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_nothrow_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_nothrow_swappable_with has wrong value"
+#endif
+
+void test01()
+{
+  // Check for required typedefs
+  typedef is_nothrow_swappable_with<int, 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;
+}
Index: testsuite/20_util/is_nothrow_swappable_with/value.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable_with/value.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable_with/value.cc	(working copy)
@@ -0,0 +1,145 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_nothrow_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_nothrow_swappable_with has wrong value"
+#endif
+
+namespace funny {
+  struct T0 {};
+  
+  void swap(T0, T0) noexcept;
+
+  struct T1
+  {
+    friend void swap(T1, T1) noexcept;
+  };
+    
+  struct T2 {};
+  struct T3 {}; 
+  
+  void swap(T2, T3) noexcept;
+  void swap(T3, T2) noexcept;
+  
+  struct T4 { operator T0() const noexcept; };
+  
+  struct F0 {};
+
+  void swap(F0, F0) = delete;
+  
+  struct F1 {};
+  
+  void swap(F1, F1);
+
+  struct F2 {};
+  
+  void swap(F0, F2) noexcept;
+  void swap(F2, F0);
+  
+  struct F3
+  {
+    friend void swap(F3, F3) = delete;
+  };
+
+  struct F4
+  {
+    friend void swap(F4, F4);
+  };
+  
+  struct F5 { operator T0() const; };
+
+  struct BoolLike {};
+
+  void swap(BoolLike, bool&) noexcept;
+  void swap(bool&, BoolLike) noexcept;
+
+  struct BoolLikeErr {};
+
+  void swap(BoolLikeErr, bool&);
+  void swap(bool&, BoolLikeErr) noexcept;
+}
+
+void test01()
+{
+  using std::is_nothrow_swappable_with;
+  using namespace __gnu_test;
+  // Positive tests.
+  static_assert(test_property<is_nothrow_swappable_with, int&, int&>(true), 
+    "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T0, 
+    funny::T0>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T0, 
+    const funny::T0>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T1, 
+    funny::T1>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T1, 
+    const funny::T1>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T2, 
+    funny::T3>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T3, 
+    funny::T2>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T0, 
+    funny::T4>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T4, 
+    funny::T0>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::BoolLike, 
+    bool&>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, const funny::BoolLike,
+    bool&>(true), "");
+  
+  // Negative tests.
+  static_assert(test_property<is_nothrow_swappable_with, const int&, 
+    const int&>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, int&, 
+    unsigned&>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F0, 
+    funny::F0>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F0, 
+    const funny::F0>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F1, 
+    funny::F1>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F1, 
+    const funny::F1>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F0, 
+    funny::F2>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F2, 
+    funny::F0>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F3, 
+    funny::F3>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F3, 
+    const funny::F3>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F4, 
+    funny::F4>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F4, 
+    const funny::F4>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T0, 
+    funny::F5>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F5, 
+    funny::T0>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::BoolLikeErr, 
+    bool&>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, 
+    const funny::BoolLikeErr, bool&>(false), "");
+}
Index: testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc	(working copy)
@@ -0,0 +1,36 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_nothrow_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_nothrow_swappable_with has wrong value"
+#endif
+
+namespace std
+{
+  typedef short test_type;
+  typedef double test_type_2;
+  template struct std::is_nothrow_swappable_with<test_type, test_type>;
+  template struct std::is_nothrow_swappable_with<test_type, test_type_2>;
+  template struct std::is_nothrow_swappable_with<test_type_2, test_type_2>;
+}
Index: testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc	(working copy)
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_nothrow_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_nothrow_swappable_with has wrong value"
+#endif
+
+void test01()
+{
+  // Check for required typedefs
+  typedef is_nothrow_swappable_with<int, 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;
+}
Index: testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable_with/requirements/explicit_instantiation.cc	(working copy)
@@ -0,0 +1,36 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_nothrow_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_nothrow_swappable_with has wrong value"
+#endif
+
+namespace std
+{
+  typedef short test_type;
+  typedef double test_type_2;
+  template struct std::is_nothrow_swappable_with<test_type, test_type>;
+  template struct std::is_nothrow_swappable_with<test_type, test_type_2>;
+  template struct std::is_nothrow_swappable_with<test_type_2, test_type_2>;
+}
Index: testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable_with/requirements/typedefs.cc	(working copy)
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_nothrow_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_nothrow_swappable_with has wrong value"
+#endif
+
+void test01()
+{
+  // Check for required typedefs
+  typedef is_nothrow_swappable_with<int, 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;
+}
Index: testsuite/20_util/is_nothrow_swappable_with/value.cc
===================================================================
--- testsuite/20_util/is_nothrow_swappable_with/value.cc	(nonexistent)
+++ testsuite/20_util/is_nothrow_swappable_with/value.cc	(working copy)
@@ -0,0 +1,145 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_nothrow_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_nothrow_swappable_with has wrong value"
+#endif
+
+namespace funny {
+  struct T0 {};
+  
+  void swap(T0, T0) noexcept;
+
+  struct T1
+  {
+    friend void swap(T1, T1) noexcept;
+  };
+    
+  struct T2 {};
+  struct T3 {}; 
+  
+  void swap(T2, T3) noexcept;
+  void swap(T3, T2) noexcept;
+  
+  struct T4 { operator T0() const noexcept; };
+  
+  struct F0 {};
+
+  void swap(F0, F0) = delete;
+  
+  struct F1 {};
+  
+  void swap(F1, F1);
+
+  struct F2 {};
+  
+  void swap(F0, F2) noexcept;
+  void swap(F2, F0);
+  
+  struct F3
+  {
+    friend void swap(F3, F3) = delete;
+  };
+
+  struct F4
+  {
+    friend void swap(F4, F4);
+  };
+  
+  struct F5 { operator T0() const; };
+
+  struct BoolLike {};
+
+  void swap(BoolLike, bool&) noexcept;
+  void swap(bool&, BoolLike) noexcept;
+
+  struct BoolLikeErr {};
+
+  void swap(BoolLikeErr, bool&);
+  void swap(bool&, BoolLikeErr) noexcept;
+}
+
+void test01()
+{
+  using std::is_nothrow_swappable_with;
+  using namespace __gnu_test;
+  // Positive tests.
+  static_assert(test_property<is_nothrow_swappable_with, int&, int&>(true), 
+    "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T0, 
+    funny::T0>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T0, 
+    const funny::T0>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T1, 
+    funny::T1>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T1, 
+    const funny::T1>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T2, 
+    funny::T3>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T3, 
+    funny::T2>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T0, 
+    funny::T4>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T4, 
+    funny::T0>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::BoolLike, 
+    bool&>(true), "");
+  static_assert(test_property<is_nothrow_swappable_with, const funny::BoolLike,
+    bool&>(true), "");
+  
+  // Negative tests.
+  static_assert(test_property<is_nothrow_swappable_with, const int&, 
+    const int&>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, int&, 
+    unsigned&>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F0, 
+    funny::F0>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F0, 
+    const funny::F0>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F1, 
+    funny::F1>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F1, 
+    const funny::F1>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F0, 
+    funny::F2>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F2, 
+    funny::F0>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F3, 
+    funny::F3>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F3, 
+    const funny::F3>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F4, 
+    funny::F4>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F4, 
+    const funny::F4>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::T0, 
+    funny::F5>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::F5, 
+    funny::T0>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, funny::BoolLikeErr, 
+    bool&>(false), "");
+  static_assert(test_property<is_nothrow_swappable_with, 
+    const funny::BoolLikeErr, bool&>(false), "");
+}
Index: testsuite/20_util/is_swappable/requirements/explicit_instantiation_ext.cc
===================================================================
--- testsuite/20_util/is_swappable/requirements/explicit_instantiation_ext.cc	(nonexistent)
+++ testsuite/20_util/is_swappable/requirements/explicit_instantiation_ext.cc	(working copy)
@@ -0,0 +1,27 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2015-2016 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_swappable<test_type>;
+}
Index: testsuite/20_util/is_swappable/requirements/typedefs_ext.cc
===================================================================
--- testsuite/20_util/is_swappable/requirements/typedefs_ext.cc	(nonexistent)
+++ testsuite/20_util/is_swappable/requirements/typedefs_ext.cc	(working copy)
@@ -0,0 +1,31 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2015-2016 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_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;
+}
Index: testsuite/20_util/is_swappable/value.h
===================================================================
--- testsuite/20_util/is_swappable/value.h	(nonexistent)
+++ testsuite/20_util/is_swappable/value.h	(working copy)
@@ -0,0 +1,203 @@
+// Copyright (C) 2015-2016 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>
+
+#if defined(test_std_is_swappable)
+#  ifndef __cpp_lib_is_swappable
+#   error "Feature-test macro for is_swappable missing"
+#  elif __cpp_lib_is_swappable != 201603
+#   error "Feature-test macro for is_swappable has wrong value"
+#  endif
+// Test std::is_swappable:
+template<class T>
+using is_swappable = std::is_swappable<T>; 
+#elif defined(test_std_is_swappable_ext)
+// Test our __is_swappable extension:
+template<class T>
+using is_swappable = std::__is_swappable<T>;
+#else
+# error "Either test_std_is_swappable or test_std_is_swappable_ext" \
+        "need to be defined"
+#endif
+
+namespace funny {
+  struct F {};
+  void swap(F&, F&) = delete;
+  void swap(F(&)[5], F(&)[5]);
+
+  struct F2
+  {
+    friend void swap(F2&, F2&) = delete;
+  };
+
+  struct F3
+  {
+    friend void swap(F3&, F3) {}
+  };
+}
+void test01()
+{
+  using namespace __gnu_test;
+  // Positive tests.
+  static_assert(test_property<is_swappable, int>(true), "");
+  static_assert(test_property<is_swappable, bool>(true), "");
+  static_assert(test_property<is_swappable, decltype(nullptr)>(true), "");
+  static_assert(test_property<is_swappable, int&>(true), "");
+  static_assert(test_property<is_swappable, int&&>(true), "");
+  static_assert(test_property<is_swappable, int[1]>(true), "");
+  static_assert(test_property<is_swappable, int[1][2]>(true), "");
+  static_assert(test_property<is_swappable, int[1][2][3]>(true), "");
+  static_assert(test_property<is_swappable, int(&)[1]>(true), "");
+  static_assert(test_property<is_swappable, funny::F[5]>(true), "");
+  static_assert(test_property<is_swappable, funny::F3>(true), "");
+  static_assert(test_property<is_swappable, funny::F3[1]>(true), "");
+  static_assert(test_property<is_swappable, funny::F3[1][2]>(true), "");
+  static_assert(test_property<is_swappable, funny::F3[1][2][3]>(true), "");
+  static_assert(test_property<is_swappable,
+    ThrowCopyConsClass>(true), "");
+  static_assert(test_property<is_swappable, EnumType>(true), "");
+  static_assert(test_property<is_swappable, PODType>(true), "");
+  static_assert(test_property<is_swappable, UnionType>(true), "");
+  static_assert(test_property<is_swappable, construct::SE>(true), "");
+  static_assert(test_property<is_swappable, construct::Empty>(true), "");
+  static_assert(test_property<is_swappable, void*>(true), "");
+  static_assert(test_property<is_swappable, int const*>(true), "");
+  static_assert(test_property<is_swappable, ClassType*>(true), "");
+  static_assert(test_property<is_swappable, int ClassType::*>(true), "");
+  static_assert(test_property<is_swappable,
+    void (ClassType::*)()>(true), "");
+  static_assert(test_property<is_swappable,
+    construct::Nontrivial>(true), "");
+  static_assert(test_property<is_swappable, construct::Any>(true), "");
+  static_assert(test_property<is_swappable, construct::nAny>(true), "");
+  static_assert(test_property<is_swappable,
+		std::pair<int, int>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::pair<int, int>[1]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::pair<int, int>[1][2]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::pair<int, int>[1][2][3]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::pair<construct::Nontrivial, construct::Nontrivial>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::tuple<int>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::tuple<int>[1]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::tuple<int>[1][2]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::tuple<int>[1][2][3]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::tuple<>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::tuple<>[1]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::tuple<>[1][2]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::tuple<>[1][2][3]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::tuple<construct::Nontrivial>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::array<int, 1>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::array<int, 1>[1]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::array<int, 1>[1][2]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::array<int, 1>[1][2][3]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::array<construct::Nontrivial, 1>>(true), "");
+  static_assert(test_property<is_swappable,
+        std::array<int, 0>>(true), "");
+  static_assert(test_property<is_swappable,
+        std::array<construct::DelCopy, 0>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::queue<int>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::queue<int>[1]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::queue<int>[1][2]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::queue<int>[1][2][3]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::queue<construct::Nontrivial>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::priority_queue<int>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::priority_queue<int>[1]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::priority_queue<int>[1][2]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::priority_queue<int>[1][2][3]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::priority_queue<construct::Nontrivial>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::stack<int>>(true), "");
+  static_assert(test_property<is_swappable,
+		std::stack<int>[1]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::stack<int>[1][2]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::stack<int>[1][2][3]>(true), "");
+  static_assert(test_property<is_swappable,
+		std::stack<construct::Nontrivial>>(true), "");
+  // Negative tests.
+  static_assert(test_property<is_swappable, void>(false), "");
+  static_assert(test_property<is_swappable, const void>(false), "");
+  static_assert(test_property<is_swappable, void()>(false), "");
+  static_assert(test_property<is_swappable, void() const>(false), "");
+  static_assert(test_property<is_swappable, void() volatile>(false), "");
+  static_assert(test_property<is_swappable,
+    void() const volatile>(false), "");
+  static_assert(test_property<is_swappable, const int>(false), "");
+  static_assert(test_property<is_swappable, const bool>(false), "");
+  static_assert(test_property<is_swappable, int[]>(false), "");
+  static_assert(test_property<is_swappable, const int[]>(false), "");
+  static_assert(test_property<is_swappable, int[][1]>(false), "");
+  static_assert(test_property<is_swappable, const int[1]>(false), "");
+  static_assert(test_property<is_swappable, const int[1][2]>(false), "");
+  static_assert(test_property<is_swappable, const int[1][2][3]>(false), "");
+  static_assert(test_property<is_swappable, construct::DelCopy>(false), "");
+  static_assert(test_property<is_swappable,
+    construct::Abstract>(false), "");
+  static_assert(test_property<is_swappable,
+    construct::NontrivialUnion>(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_swappable, funny::F[1][2]>(false), "");
+  static_assert(test_property<is_swappable, funny::F[1][2][3]>(false), "");
+  static_assert(test_property<is_swappable, funny::F[4]>(false), "");
+  static_assert(test_property<is_swappable, construct::DelCopy>(false), "");
+  static_assert(test_property<is_swappable,
+     DeletedCopyAssignClass>(false), "");
+  static_assert(test_property<is_swappable,
+     DeletedMoveAssignClass>(false), "");
+  static_assert(test_property<is_swappable, funny::F2>(false), "");
+  static_assert(test_property<is_swappable, funny::F2[1]>(false), "");
+  static_assert(test_property<is_swappable, funny::F2[1][2]>(false), "");
+  static_assert(test_property<is_swappable, funny::F2[1][2][3]>(false), "");
+  static_assert(test_property<is_swappable, funny::F2[4]>(false), "");
+  static_assert(test_property<is_swappable, funny::F2[5]>(false), "");
+}
Index: testsuite/20_util/is_swappable/value_ext.cc
===================================================================
--- testsuite/20_util/is_swappable/value_ext.cc	(nonexistent)
+++ testsuite/20_util/is_swappable/value_ext.cc	(working copy)
@@ -0,0 +1,22 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2015-2016 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/>.
+
+#define test_std_is_swappable_ext
+#include "./value.h"
Index: testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc
===================================================================
--- testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc	(nonexistent)
+++ testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc	(working copy)
@@ -0,0 +1,36 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_swappable_with has wrong value"
+#endif
+
+namespace std
+{
+  typedef short test_type;
+  typedef double test_type_2;
+  template struct std::is_swappable_with<test_type, test_type>;
+  template struct std::is_swappable_with<test_type, test_type_2>;
+  template struct std::is_swappable_with<test_type_2, test_type_2>;
+}
Index: testsuite/20_util/is_swappable_with/requirements/typedefs.cc
===================================================================
--- testsuite/20_util/is_swappable_with/requirements/typedefs.cc	(nonexistent)
+++ testsuite/20_util/is_swappable_with/requirements/typedefs.cc	(working copy)
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_swappable_with has wrong value"
+#endif
+
+void test01()
+{
+  // Check for required typedefs
+  typedef is_swappable_with<int, 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;
+}
Index: testsuite/20_util/is_swappable_with/value.cc
===================================================================
--- testsuite/20_util/is_swappable_with/value.cc	(nonexistent)
+++ testsuite/20_util/is_swappable_with/value.cc	(working copy)
@@ -0,0 +1,113 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_swappable_with has wrong value"
+#endif
+
+namespace funny {
+  struct T0 {};
+  
+  void swap(T0, T0);
+  
+  struct T1 {};
+  struct T2 {}; 
+  
+  void swap(T1, T2);
+  void swap(T2, T1);
+  
+  struct BoolLike {};
+
+  void swap(BoolLike, bool&);
+  void swap(bool&, BoolLike);
+  
+  struct F0 {};
+
+  void swap(F0, F0) = delete;
+  
+  struct F1 {};
+  
+  void swap(F0, F1) = delete;
+  void swap(F1, F0) = delete;
+  
+  struct F2 {};
+  struct F3 {};
+  
+  void swap(F2, F3);
+  void swap(F3, F2) = delete;
+  
+  struct F4
+  {
+    friend void swap(F4, F4) = delete;
+  };
+}
+
+void test01()
+{
+  using std::is_swappable_with;
+  using namespace __gnu_test;
+  // Positive tests.
+  static_assert(test_property<is_swappable_with, int&, int&>(true), "");
+  static_assert(test_property<is_swappable_with, funny::T0, 
+    funny::T0>(true), "");
+  static_assert(test_property<is_swappable_with, funny::T0, 
+    const funny::T0>(true), "");
+  static_assert(test_property<is_swappable_with, funny::T1, 
+    funny::T2>(true), "");
+  static_assert(test_property<is_swappable_with, funny::T2, 
+    funny::T1>(true), "");
+  static_assert(test_property<is_swappable_with, funny::BoolLike, 
+    bool&>(true), "");
+  static_assert(test_property<is_swappable_with, const funny::BoolLike,
+    bool&>(true), "");
+
+  // Negative tests.
+  static_assert(test_property<is_swappable_with, int, int>(false), "");
+  static_assert(test_property<is_swappable_with, int&, unsigned&>(false), "");
+  static_assert(test_property<is_swappable_with, const int&, 
+    const int&>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F0, 
+    funny::F0>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F0, 
+    const funny::F0>(false), "");
+  static_assert(test_property<is_swappable_with, funny::T0, 
+    funny::T1>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F0, 
+    funny::F1>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F0, 
+    const funny::F1>(false), "");
+  static_assert(test_property<is_swappable_with, const funny::F0, 
+    funny::F1>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F2, 
+    funny::F3>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F2, 
+    const funny::F3>(false), "");
+  static_assert(test_property<is_swappable_with, const funny::F2, 
+    funny::F3>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F4, 
+    funny::F4>(false), "");
+  static_assert(test_property<is_swappable_with, funny::BoolLike, 
+    funny::BoolLike>(false), "");
+}
Index: testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc
===================================================================
--- testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc	(nonexistent)
+++ testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc	(working copy)
@@ -0,0 +1,36 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_swappable_with has wrong value"
+#endif
+
+namespace std
+{
+  typedef short test_type;
+  typedef double test_type_2;
+  template struct std::is_swappable_with<test_type, test_type>;
+  template struct std::is_swappable_with<test_type, test_type_2>;
+  template struct std::is_swappable_with<test_type_2, test_type_2>;
+}
Index: testsuite/20_util/is_swappable_with/requirements/typedefs.cc
===================================================================
--- testsuite/20_util/is_swappable_with/requirements/typedefs.cc	(nonexistent)
+++ testsuite/20_util/is_swappable_with/requirements/typedefs.cc	(working copy)
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_swappable_with has wrong value"
+#endif
+
+void test01()
+{
+  // Check for required typedefs
+  typedef is_swappable_with<int, 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;
+}
Index: testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc
===================================================================
--- testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc	(nonexistent)
+++ testsuite/20_util/is_swappable_with/requirements/explicit_instantiation.cc	(working copy)
@@ -0,0 +1,36 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_swappable_with has wrong value"
+#endif
+
+namespace std
+{
+  typedef short test_type;
+  typedef double test_type_2;
+  template struct std::is_swappable_with<test_type, test_type>;
+  template struct std::is_swappable_with<test_type, test_type_2>;
+  template struct std::is_swappable_with<test_type_2, test_type_2>;
+}
Index: testsuite/20_util/is_swappable_with/requirements/typedefs.cc
===================================================================
--- testsuite/20_util/is_swappable_with/requirements/typedefs.cc	(nonexistent)
+++ testsuite/20_util/is_swappable_with/requirements/typedefs.cc	(working copy)
@@ -0,0 +1,37 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_swappable_with has wrong value"
+#endif
+
+void test01()
+{
+  // Check for required typedefs
+  typedef is_swappable_with<int, 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;
+}
Index: testsuite/20_util/is_swappable_with/value.cc
===================================================================
--- testsuite/20_util/is_swappable_with/value.cc	(nonexistent)
+++ testsuite/20_util/is_swappable_with/value.cc	(working copy)
@@ -0,0 +1,113 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 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>
+
+#ifndef __cpp_lib_is_swappable
+# error "Feature-test macro for is_swappable_with missing"
+#elif __cpp_lib_is_swappable != 201603
+# error "Feature-test macro for is_swappable_with has wrong value"
+#endif
+
+namespace funny {
+  struct T0 {};
+  
+  void swap(T0, T0);
+  
+  struct T1 {};
+  struct T2 {}; 
+  
+  void swap(T1, T2);
+  void swap(T2, T1);
+  
+  struct BoolLike {};
+
+  void swap(BoolLike, bool&);
+  void swap(bool&, BoolLike);
+  
+  struct F0 {};
+
+  void swap(F0, F0) = delete;
+  
+  struct F1 {};
+  
+  void swap(F0, F1) = delete;
+  void swap(F1, F0) = delete;
+  
+  struct F2 {};
+  struct F3 {};
+  
+  void swap(F2, F3);
+  void swap(F3, F2) = delete;
+  
+  struct F4
+  {
+    friend void swap(F4, F4) = delete;
+  };
+}
+
+void test01()
+{
+  using std::is_swappable_with;
+  using namespace __gnu_test;
+  // Positive tests.
+  static_assert(test_property<is_swappable_with, int&, int&>(true), "");
+  static_assert(test_property<is_swappable_with, funny::T0, 
+    funny::T0>(true), "");
+  static_assert(test_property<is_swappable_with, funny::T0, 
+    const funny::T0>(true), "");
+  static_assert(test_property<is_swappable_with, funny::T1, 
+    funny::T2>(true), "");
+  static_assert(test_property<is_swappable_with, funny::T2, 
+    funny::T1>(true), "");
+  static_assert(test_property<is_swappable_with, funny::BoolLike, 
+    bool&>(true), "");
+  static_assert(test_property<is_swappable_with, const funny::BoolLike,
+    bool&>(true), "");
+
+  // Negative tests.
+  static_assert(test_property<is_swappable_with, int, int>(false), "");
+  static_assert(test_property<is_swappable_with, int&, unsigned&>(false), "");
+  static_assert(test_property<is_swappable_with, const int&, 
+    const int&>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F0, 
+    funny::F0>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F0, 
+    const funny::F0>(false), "");
+  static_assert(test_property<is_swappable_with, funny::T0, 
+    funny::T1>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F0, 
+    funny::F1>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F0, 
+    const funny::F1>(false), "");
+  static_assert(test_property<is_swappable_with, const funny::F0, 
+    funny::F1>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F2, 
+    funny::F3>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F2, 
+    const funny::F3>(false), "");
+  static_assert(test_property<is_swappable_with, const funny::F2, 
+    funny::F3>(false), "");
+  static_assert(test_property<is_swappable_with, funny::F4, 
+    funny::F4>(false), "");
+  static_assert(test_property<is_swappable_with, funny::BoolLike, 
+    funny::BoolLike>(false), "");
+}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Patch] Implement is_[nothrow_]swappable (p0185r1)
  2016-05-17 18:39 [Patch] Implement is_[nothrow_]swappable (p0185r1) Daniel Krügler
@ 2016-05-23 11:50 ` Jonathan Wakely
  2016-05-25  8:32   ` Daniel Krügler
  0 siblings, 1 reply; 4+ messages in thread
From: Jonathan Wakely @ 2016-05-23 11:50 UTC (permalink / raw)
  To: Daniel Krügler; +Cc: libstdc++, gcc-patches List

On 17/05/16 20:39 +0200, Daniel Krügler wrote:
>This is an implementation of the Standard is_swappable traits according to
>
>http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0185r1.html
>
>During that work it has been found that std::array's member swap's exception
>specification for zero-size arrays was incorrectly depending on the value_type
>and that was fixed as well.

This looks good to me, I'll get it committed (with some adjustment to
the ChangeLog format) - thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Patch] Implement is_[nothrow_]swappable (p0185r1)
  2016-05-23 11:50 ` Jonathan Wakely
@ 2016-05-25  8:32   ` Daniel Krügler
  2016-05-26  7:04     ` Mike Stump
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Krügler @ 2016-05-25  8:32 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches List

2016-05-23 13:50 GMT+02:00 Jonathan Wakely <jwakely@redhat.com>:
> On 17/05/16 20:39 +0200, Daniel Krügler wrote:
>>
>> This is an implementation of the Standard is_swappable traits according to
>>
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0185r1.html
>>
>> During that work it has been found that std::array's member swap's
>> exception
>> specification for zero-size arrays was incorrectly depending on the
>> value_type
>> and that was fixed as well.
>
> This looks good to me, I'll get it committed (with some adjustment to
> the ChangeLog format) - thanks.

Unfortunately I need to withdraw the suggested patch. Besides some
obvious errors there are issues that require me to get the testsuite
run on my Windows system, which had not yet succeeded.

I would appreciate, if anyone who has succeeded to run the test suite
on a Windows system (preferably mingw), could contact me off-list.

Thanks,

- Daniel


-- 

________________________________
SavedURI :Show URLShow URLSavedURI :
SavedURI :Hide URLHide URLSavedURI :
https://mail.google.com/_/scs/mail-static/_/js/k=gmail.main.de.LEt2fN4ilLE.O/m=m_i,t,it/am=OCMOBiHj9kJxhnelj6j997_NLil29vVAOBGeBBRgJwD-m_0_8B_AD-qOEw/rt=h/d=1/rs=AItRSTODy9wv1JKZMABIG3Ak8ViC4kuOWA?random=1395770800154https://mail.google.com/_/scs/mail-static/_/js/k=gmail.main.de.LEt2fN4ilLE.O/m=m_i,t,it/am=OCMOBiHj9kJxhnelj6j997_NLil29vVAOBGeBBRgJwD-m_0_8B_AD-qOEw/rt=h/d=1/rs=AItRSTODy9wv1JKZMABIG3Ak8ViC4kuOWA?random=1395770800154
________________________________

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Patch] Implement is_[nothrow_]swappable (p0185r1)
  2016-05-25  8:32   ` Daniel Krügler
@ 2016-05-26  7:04     ` Mike Stump
  0 siblings, 0 replies; 4+ messages in thread
From: Mike Stump @ 2016-05-26  7:04 UTC (permalink / raw)
  To: Daniel Krügler; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

On May 24, 2016, at 9:50 PM, Daniel Krügler <daniel.kruegler@gmail.com> wrote:
> 
> 2016-05-23 13:50 GMT+02:00 Jonathan Wakely <jwakely@redhat.com>:
>> On 17/05/16 20:39 +0200, Daniel Krügler wrote:
>>> 
>>> This is an implementation of the Standard is_swappable traits according to
>>> 
>>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0185r1.html
>>> 
>>> During that work it has been found that std::array's member swap's
>>> exception
>>> specification for zero-size arrays was incorrectly depending on the
>>> value_type
>>> and that was fixed as well.
>> 
>> This looks good to me, I'll get it committed (with some adjustment to
>> the ChangeLog format) - thanks.
> 
> Unfortunately I need to withdraw the suggested patch. Besides some
> obvious errors there are issues that require me to get the testsuite
> run on my Windows system, which had not yet succeeded.
> 
> I would appreciate, if anyone who has succeeded to run the test suite
> on a Windows system (preferably mingw), could contact me off-list.

So, you can fix up the code that matters, and re-post the that code, and merely say the patch doesn't have testing on it and ask others to run the test suite for you.  Once you hear back and that the patch tests out well, you can then seek approval for inclusion, even though you never tested it.  Longer term, it is handy to be able to run the test suite yourself...  If Windows proves to be a pain, you you can run a VM with linux on it, and then run the test suite in the linux VM on windows.  Also, you can grab cygwin, testing there should be very, very close to just install cygwin, make && make check.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-05-25 19:37 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-17 18:39 [Patch] Implement is_[nothrow_]swappable (p0185r1) Daniel Krügler
2016-05-23 11:50 ` Jonathan Wakely
2016-05-25  8:32   ` Daniel Krügler
2016-05-26  7:04     ` Mike Stump

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).