[libcxx] r267079 - Add is_swappable/is_nothrow_swappable traits

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 21 16:38:59 PDT 2016


Author: ericwf
Date: Thu Apr 21 18:38:59 2016
New Revision: 267079

URL: http://llvm.org/viewvc/llvm-project?rev=267079&view=rev
Log:
Add is_swappable/is_nothrow_swappable traits

Added:
    libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp
    libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp
    libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp
    libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp
    libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp
Modified:
    libcxx/trunk/include/algorithm
    libcxx/trunk/include/array
    libcxx/trunk/include/map
    libcxx/trunk/include/memory
    libcxx/trunk/include/queue
    libcxx/trunk/include/stack
    libcxx/trunk/include/type_traits
    libcxx/trunk/include/utility
    libcxx/trunk/test/std/containers/sequences/array/array.special/swap.pass.cpp
    libcxx/trunk/test/std/containers/sequences/array/array.swap/swap.pass.cpp
    libcxx/trunk/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp
    libcxx/trunk/test/std/utilities/utility/utility.swap/swap.pass.cpp
    libcxx/trunk/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
    libcxx/trunk/www/cxx1z_status.html

Modified: libcxx/trunk/include/algorithm
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/algorithm?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/include/algorithm (original)
+++ libcxx/trunk/include/algorithm Thu Apr 21 18:38:59 2016
@@ -630,7 +630,7 @@ template <class BidirectionalIterator, c
 #include <initializer_list>
 #include <type_traits>
 #include <cstring>
-#include <utility>
+#include <utility> // needed to provide swap_ranges.
 #include <memory>
 #include <iterator>
 #include <cstddef>

Modified: libcxx/trunk/include/array
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/array?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/include/array (original)
+++ libcxx/trunk/include/array Thu Apr 21 18:38:59 2016
@@ -34,7 +34,7 @@ struct array
 
     // No explicit construct/copy/destroy for aggregate type
     void fill(const T& u);
-    void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));
+    void swap(array& a) noexcept(is_nothrow_swappable_v<T>);
 
     // iterators:
     iterator begin() noexcept;
@@ -141,8 +141,15 @@ struct _LIBCPP_TYPE_VIS_ONLY array
     _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u)
         {_VSTD::fill_n(__elems_, _Size, __u);}
     _LIBCPP_INLINE_VISIBILITY
-    void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
-        {_VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);}
+    void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value)
+        { __swap_dispatch((std::integral_constant<bool, _Size == 0>()), __a); }
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __swap_dispatch(std::true_type, array&) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __swap_dispatch(std::false_type, array& __a)
+        { _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);}
 
     // iterators:
     _LIBCPP_INLINE_VISIBILITY
@@ -276,11 +283,12 @@ template <class _Tp, size_t _Size>
 inline _LIBCPP_INLINE_VISIBILITY
 typename enable_if
 <
+    _Size == 0 ||
     __is_swappable<_Tp>::value,
     void
 >::type
 swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y)
-                                  _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
+                                  _NOEXCEPT_(noexcept(__x.swap(__y)))
 {
     __x.swap(__y);
 }

Modified: libcxx/trunk/include/map
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/map?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/include/map (original)
+++ libcxx/trunk/include/map Thu Apr 21 18:38:59 2016
@@ -162,7 +162,7 @@ public:
 
     void swap(map& m)
         noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-            __is_nothrow_swappable<key_compare>::value); // C++17
+            is_nothrow_swappable<key_compare>::value); // C++17
 
     // observers:
     allocator_type get_allocator() const noexcept;
@@ -357,7 +357,7 @@ public:
 
     void swap(multimap& m)
         noexcept(allocator_traits<allocator_type>::is_always_equal::value &&
-            __is_nothrow_swappable<key_compare>::value); // C++17
+            is_nothrow_swappable<key_compare>::value); // C++17
 
     // observers:
     allocator_type get_allocator() const noexcept;

Modified: libcxx/trunk/include/memory
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/include/memory (original)
+++ libcxx/trunk/include/memory Thu Apr 21 18:38:59 2016
@@ -2974,7 +2974,10 @@ private:
 
 template <class _Tp, class _Dp>
 inline _LIBCPP_INLINE_VISIBILITY
-void
+typename enable_if<
+    __is_swappable<_Dp>::value,
+    void
+>::type
 swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
 
 template <class _T1, class _D1, class _T2, class _D2>

Modified: libcxx/trunk/include/queue
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/queue?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/include/queue (original)
+++ libcxx/trunk/include/queue Thu Apr 21 18:38:59 2016
@@ -66,7 +66,7 @@ public:
     template <class... Args> void emplace(Args&&... args);
     void pop();
 
-    void swap(queue& q) noexcept(noexcept(swap(c, q.c)));
+    void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>)
 };
 
 template <class T, class Container>
@@ -153,7 +153,8 @@ public:
     void pop();
 
     void swap(priority_queue& q)
-        noexcept(noexcept(swap(c, q.c)) && noexcept(swap(comp.q.comp)));
+        noexcept(is_nothrow_swappable_v<Container> &&
+                 is_nothrow_swappable_v<Comp>)
 };
 
 template <class T, class Container, class Compare>
@@ -369,7 +370,10 @@ operator<=(const queue<_Tp, _Container>&
 
 template <class _Tp, class _Container>
 inline _LIBCPP_INLINE_VISIBILITY
-void
+typename enable_if<
+    __is_swappable<_Container>::value,
+    void
+>::type
 swap(queue<_Tp, _Container>& __x, queue<_Tp, _Container>& __y)
     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
 {
@@ -700,7 +704,11 @@ priority_queue<_Tp, _Container, _Compare
 
 template <class _Tp, class _Container, class _Compare>
 inline _LIBCPP_INLINE_VISIBILITY
-void
+typename enable_if<
+    __is_swappable<_Container>::value
+    && __is_swappable<_Compare>::value,
+    void
+>::type
 swap(priority_queue<_Tp, _Container, _Compare>& __x,
      priority_queue<_Tp, _Container, _Compare>& __y)
     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))

Modified: libcxx/trunk/include/stack
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/stack?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/include/stack (original)
+++ libcxx/trunk/include/stack Thu Apr 21 18:38:59 2016
@@ -58,7 +58,7 @@ public:
     template <class... Args> void emplace(Args&&... args);
     void pop();
 
-    void swap(stack& c) noexcept(noexcept(swap(c, q.c)));
+    void swap(stack& c) noexcept(is_nothrow_swappable_v<Container>)
 };
 
 template <class T, class Container>
@@ -275,7 +275,10 @@ operator<=(const stack<_Tp, _Container>&
 
 template <class _Tp, class _Container>
 inline _LIBCPP_INLINE_VISIBILITY
-void
+typename enable_if<
+    __is_swappable<_Container>::value,
+    void
+>::type
 swap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y)
     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
 {

Modified: libcxx/trunk/include/type_traits
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/include/type_traits (original)
+++ libcxx/trunk/include/type_traits Thu Apr 21 18:38:59 2016
@@ -105,6 +105,8 @@ namespace std
     template <class T, class U>       struct is_assignable;
     template <class T>                struct is_copy_assignable;
     template <class T>                struct is_move_assignable;
+    template <class T, class U>       struct is_swappable_with;       // C++17
+    template <class T>                struct is_swappable;            // C++17
     template <class T>                struct is_destructible;
 
     template <class T, class... Args> struct is_trivially_constructible;
@@ -123,6 +125,8 @@ namespace std
     template <class T, class U>       struct is_nothrow_assignable;
     template <class T>                struct is_nothrow_copy_assignable;
     template <class T>                struct is_nothrow_move_assignable;
+    template <class T, class U>       struct is_nothrow_swappable_with; // C++17
+    template <class T>                struct is_nothrow_swappable;      // C++17
     template <class T>                struct is_nothrow_destructible;
 
     template <class T> struct has_virtual_destructor;
@@ -300,6 +304,10 @@ namespace std
         = is_copy_assignable<T>::value;                                  // C++17
       template <class T> constexpr bool is_move_assignable_v
         = is_move_assignable<T>::value;                                  // C++17
+      template <class T, class U> constexpr bool is_swappable_with_v
+        = is_swappable_with<T, U>::value;                                // C++17
+      template <class T> constexpr bool is_swappable_v
+        = is_swappable<T>::value;                                        // C++17
       template <class T> constexpr bool is_destructible_v
         = is_destructible<T>::value;                                     // C++17
       template <class T, class... Args> constexpr bool is_trivially_constructible_v
@@ -332,6 +340,10 @@ namespace std
         = is_nothrow_copy_assignable<T>::value;                          // C++17
       template <class T> constexpr bool is_nothrow_move_assignable_v
         = is_nothrow_move_assignable<T>::value;                          // C++17
+      template <class T, class U> constexpr bool is_nothrow_swappable_with_v
+        = is_nothrow_swappable_with<T, U>::value;                       // C++17
+      template <class T> constexpr bool is_nothrow_swappable_v
+        = is_nothrow_swappable<T>::value;                               // C++17
       template <class T> constexpr bool is_nothrow_destructible_v
         = is_nothrow_destructible<T>::value;                             // C++17
       template <class T> constexpr bool has_virtual_destructor_v
@@ -4421,6 +4433,9 @@ constexpr bool is_nothrow_callable_v = i
 
 #endif  // !defined(_LIBCPP_CXX03_LANG)
 
+template <class _Tp> struct __is_swappable;
+template <class _Tp> struct __is_nothrow_swappable;
+
 template <class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
 #ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE
@@ -4440,6 +4455,13 @@ swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_n
     __y = _VSTD::move(__t);
 }
 
+template<class _Tp, size_t _Np>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<
+    __is_swappable<_Tp>::value
+>::type
+swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value);
+
 template <class _ForwardIterator1, class _ForwardIterator2>
 inline _LIBCPP_INLINE_VISIBILITY
 void
@@ -4455,55 +4477,103 @@ iter_swap(_ForwardIterator1 __a, _Forwar
 
 namespace __detail
 {
-
+// ALL generic swap overloads MUST already have a declaration available at this point.
 using _VSTD::swap;
 __nat swap(__any, __any);
 
-template <class _Tp>
-struct __swappable
+template <class _Tp, class _Up = _Tp,
+          bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value>
+struct __swappable_with
 {
-    typedef decltype(swap(_VSTD::declval<_Tp&>(), _VSTD::declval<_Tp&>())) type;
-    static const bool value = !is_same<type, __nat>::value;
+    typedef decltype(swap(_VSTD::declval<_Tp>(), _VSTD::declval<_Up>())) __swap1;
+    typedef decltype(swap(_VSTD::declval<_Up>(), _VSTD::declval<_Tp>())) __swap2;
+
+    static const bool value = !is_same<__swap1, __nat>::value
+                           && !is_same<__swap2, __nat>::value;
 };
 
+template <class _Tp, class _Up>
+struct __swappable_with<_Tp, _Up,  false> : false_type {};
+
+template <class _Tp, class _Up = _Tp, bool _Swappable = __swappable_with<_Tp, _Up>::value>
+struct __nothrow_swappable_with {
+  static const bool value =
+#ifndef _LIBCPP_HAS_NO_NOEXCEPT
+      noexcept(swap(_VSTD::declval<_Tp>(), _VSTD::declval<_Up>()))
+  &&  noexcept(swap(_VSTD::declval<_Up>(), _VSTD::declval<_Tp>()));
+#else
+      false;
+#endif
+};
+
+template <class _Tp, class _Up>
+struct __nothrow_swappable_with<_Tp, _Up, false> : false_type {};
+
 }  // __detail
 
 template <class _Tp>
 struct __is_swappable
-    : public integral_constant<bool, __detail::__swappable<_Tp>::value>
+    : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value>
 {
 };
 
-#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L)
-
-template <bool, class _Tp>
-struct __is_nothrow_swappable_imp
-    : public integral_constant<bool, noexcept(swap(_VSTD::declval<_Tp&>(),
-                                                   _VSTD::declval<_Tp&>()))>
+template <class _Tp>
+struct __is_nothrow_swappable
+    : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value>
 {
 };
 
-template <class _Tp>
-struct __is_nothrow_swappable_imp<false, _Tp>
-    : public false_type
+#if _LIBCPP_STD_VER > 14
+
+template <class _Tp, class _Up>
+struct _LIBCPP_TYPE_VIS_ONLY is_swappable_with
+    : public integral_constant<bool, __detail::__swappable_with<_Tp, _Up>::value>
 {
 };
 
 template <class _Tp>
-struct __is_nothrow_swappable
-    : public __is_nothrow_swappable_imp<__is_swappable<_Tp>::value, _Tp>
+struct _LIBCPP_TYPE_VIS_ONLY is_swappable
+    : public conditional<
+        __is_referenceable<_Tp>::value,
+        is_swappable_with<
+            typename add_lvalue_reference<_Tp>::type,
+            typename add_lvalue_reference<_Tp>::type>,
+        false_type
+    >::type
 {
 };
 
-#else  // __has_feature(cxx_noexcept)
+template <class _Tp, class _Up>
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_swappable_with
+    : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp, _Up>::value>
+{
+};
 
 template <class _Tp>
-struct __is_nothrow_swappable
-    : public false_type
+struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_swappable
+    : public conditional<
+        __is_referenceable<_Tp>::value,
+        is_nothrow_swappable_with<
+            typename add_lvalue_reference<_Tp>::type,
+            typename add_lvalue_reference<_Tp>::type>,
+        false_type
+    >::type
 {
 };
 
-#endif  // __has_feature(cxx_noexcept)
+template <class _Tp, class _Up>
+constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value;
+
+template <class _Tp>
+constexpr bool is_swappable_v = is_swappable<_Tp>::value;
+
+template <class _Tp, class _Up>
+constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_Tp, _Up>::value;
+
+template <class _Tp>
+constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value;
+
+#endif // _LIBCPP_STD_VER > 14
 
 #ifdef _LIBCPP_UNDERLYING_TYPE
 

Modified: libcxx/trunk/include/utility
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/include/utility (original)
+++ libcxx/trunk/include/utility Thu Apr 21 18:38:59 2016
@@ -82,8 +82,8 @@ struct pair
                                        is_nothrow_move_assignable<T2>::value);
     template <class U, class V> pair& operator=(pair<U, V>&& p);
 
-    void swap(pair& p) noexcept(noexcept(swap(first, p.first)) &&
-                                noexcept(swap(second, p.second)));
+    void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> &&
+                                is_nothrow_swappable_v<T2>);
 };
 
 template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
@@ -225,10 +225,6 @@ operator>=(const _Tp& __x, const _Tp& __
 
 // swap_ranges
 
-// forward
-template<class _Tp, size_t _Np>
-inline _LIBCPP_INLINE_VISIBILITY
-void swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value);
 
 template <class _ForwardIterator1, class _ForwardIterator2>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -240,9 +236,12 @@ swap_ranges(_ForwardIterator1 __first1,
     return __first2;
 }
 
+// forward declared in <type_traits>
 template<class _Tp, size_t _Np>
 inline _LIBCPP_INLINE_VISIBILITY
-void
+typename enable_if<
+    __is_swappable<_Tp>::value
+>::type
 swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
 {
     _VSTD::swap_ranges(__a, __a + _Np, __b);

Modified: libcxx/trunk/test/std/containers/sequences/array/array.special/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.special/swap.pass.cpp?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/test/std/containers/sequences/array/array.special/swap.pass.cpp (original)
+++ libcxx/trunk/test/std/containers/sequences/array/array.special/swap.pass.cpp Thu Apr 21 18:38:59 2016
@@ -14,10 +14,28 @@
 #include <array>
 #include <cassert>
 
+#include "test_macros.h"
 // std::array is explicitly allowed to be initialized with A a = { init-list };.
 // Disable the missing braces warning for this reason.
 #include "disable_missing_braces_warning.h"
 
+struct NonSwappable {
+  NonSwappable() {}
+private:
+  NonSwappable(NonSwappable const&);
+  NonSwappable& operator=(NonSwappable const&);
+};
+
+template <class Tp>
+decltype(swap(std::declval<Tp>(), std::declval<Tp>()))
+can_swap_imp(int);
+
+template <class Tp>
+std::false_type can_swap_imp(...);
+
+template <class Tp>
+struct can_swap : std::is_same<decltype(can_swap_imp<Tp>(0)), void> {};
+
 int main()
 {
     {
@@ -44,4 +62,17 @@ int main()
         assert(c1.size() == 0);
         assert(c2.size() == 0);
     }
+    {
+        typedef NonSwappable T;
+        typedef std::array<T, 42> C1;
+        typedef std::array<T, 0> C0;
+        static_assert(!can_swap<C1&>::value, "");
+        static_assert(can_swap<C0&>::value, "");
+        C0 l = {};
+        C0 r = {};
+        swap(l, r);
+#if TEST_STD_VER >= 11
+        static_assert(noexcept(swap(l, r)), "");
+#endif
+    }
 }

Modified: libcxx/trunk/test/std/containers/sequences/array/array.swap/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.swap/swap.pass.cpp?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/test/std/containers/sequences/array/array.swap/swap.pass.cpp (original)
+++ libcxx/trunk/test/std/containers/sequences/array/array.swap/swap.pass.cpp Thu Apr 21 18:38:59 2016
@@ -15,10 +15,19 @@
 #include <cassert>
 #include <array>
 
+#include "test_macros.h"
+
 // std::array is explicitly allowed to be initialized with A a = { init-list };.
 // Disable the missing braces warning for this reason.
 #include "disable_missing_braces_warning.h"
 
+struct NonSwappable {
+  NonSwappable() {}
+private:
+  NonSwappable(NonSwappable const&);
+  NonSwappable& operator=(NonSwappable const&);
+};
+
 int main()
 {
     {
@@ -70,5 +79,15 @@ int main()
         assert(c1.size() == 0);
         assert(c2.size() == 0);
     }
+    {
+        typedef NonSwappable T;
+        typedef std::array<T, 0> C0;
+        C0 l = {};
+        C0 r = {};
+        l.swap(r);
+#if TEST_STD_VER >= 11
+        static_assert(noexcept(l.swap(r)), "");
+#endif
+    }
 
 }

Modified: libcxx/trunk/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/memory/unique.ptr/unique.ptr.special/swap.pass.cpp Thu Apr 21 18:38:59 2016
@@ -16,6 +16,7 @@
 #include <memory>
 #include <cassert>
 
+#include "test_macros.h"
 #include "../deleter.h"
 
 struct A
@@ -34,6 +35,16 @@ struct A
 
 int A::count = 0;
 
+template <class T>
+struct NonSwappableDeleter {
+  explicit NonSwappableDeleter(int) {}
+  NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; }
+  void operator()(T*) const {}
+private:
+  NonSwappableDeleter(NonSwappableDeleter const&);
+
+};
+
 int main()
 {
     {
@@ -74,4 +85,18 @@ int main()
     assert(A::count == 6);
     }
     assert(A::count == 0);
+#if TEST_STD_VER >= 11
+    {
+        // test that unique_ptr's specialized swap is disabled when the deleter
+        // is non-swappable. Instead we should pick up the generic swap(T, T)
+        // and perform 3 move constructions.
+        typedef NonSwappableDeleter<int> D;
+        D  d(42);
+        int x = 42;
+        int y = 43;
+        std::unique_ptr<int, D&> p(&x, d);
+        std::unique_ptr<int, D&> p2(&y, d);
+        std::swap(p, p2);
+    }
+#endif
 }

Added: libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp?rev=267079&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable.pass.cpp Thu Apr 21 18:38:59 2016
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// type_traits
+
+// is_swappable
+
+#include <type_traits>
+#include <vector>
+#include "test_macros.h"
+
+namespace MyNS {
+
+// Make the test types non-copyable so that generic std::swap is not valid.
+struct A {
+  A(A const&) = delete;
+  A& operator=(A const&) = delete;
+};
+
+struct B {
+  B(B const&) = delete;
+  B& operator=(B const&) = delete;
+};
+
+void swap(A&, A&) noexcept {}
+void swap(B&, B&) {}
+
+struct M {
+  M(M const&) = delete;
+  M& operator=(M const&) = delete;
+};
+
+void swap(M&&, M&&) noexcept {}
+
+struct ThrowingMove {
+    ThrowingMove(ThrowingMove&&){}
+    ThrowingMove& operator=(ThrowingMove&&) {}
+};
+
+} // namespace MyNS
+
+int main()
+{
+    using namespace MyNS;
+    {
+        // Test that is_swappable applies an lvalue reference to the type.
+        static_assert(std::is_nothrow_swappable<int>::value, "");
+        static_assert(std::is_nothrow_swappable<int&>::value, "");
+        static_assert(!std::is_nothrow_swappable<M>::value, "");
+        static_assert(!std::is_nothrow_swappable<M&&>::value, "");
+    }
+    {
+        // Test that it correctly deduces the noexcept of swap.
+        static_assert(std::is_nothrow_swappable<A>::value, "");
+        static_assert(!std::is_nothrow_swappable<B>::value
+                      && std::is_swappable<B>::value, "");
+        static_assert(!std::is_nothrow_swappable<ThrowingMove>::value
+                      && std::is_swappable<ThrowingMove>::value);
+    }
+    {
+        // Test that it doesn't drop the qualifiers
+        static_assert(!std::is_nothrow_swappable<const A>::value, "");
+    }
+    {
+        // test non-referenceable types
+        static_assert(!std::is_nothrow_swappable<void>::value, "");
+        static_assert(!std::is_nothrow_swappable<int() const>::value, "");
+        static_assert(!std::is_nothrow_swappable<int(int, ...) const &>::value, "");
+    }
+    {
+        // test for presence of is_nothrow_swappable_v
+        static_assert(std::is_nothrow_swappable_v<int>);
+        static_assert(!std::is_nothrow_swappable_v<void>);
+    }
+}

Added: libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp?rev=267079&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_nothrow_swappable_with.pass.cpp Thu Apr 21 18:38:59 2016
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// type_traits
+
+// is_nothrow_swappable_with
+
+#include <type_traits>
+#include <vector>
+#include "test_macros.h"
+
+namespace MyNS {
+
+struct A {
+  A(A const&) = delete;
+  A& operator=(A const&) = delete;
+};
+
+struct B {
+  B(B const&) = delete;
+  B& operator=(B const&) = delete;
+};
+
+struct C {};
+struct D {};
+
+void swap(A&, A&) {}
+
+void swap(A&, B&) noexcept {}
+void swap(B&, A&) noexcept {}
+
+void swap(A&, C&) noexcept {}
+void swap(C&, A&) {}
+
+struct M {};
+
+void swap(M&&, M&&) noexcept {}
+
+} // namespace MyNS
+
+int main()
+{
+    using namespace MyNS;
+    {
+        // Test that is_swappable_with doesn't apply an lvalue reference
+        // to the type. Instead it is up to the user.
+        static_assert(!std::is_nothrow_swappable_with<int, int>::value, "");
+        static_assert(std::is_nothrow_swappable_with<int&, int&>::value, "");
+        static_assert(std::is_nothrow_swappable_with<M, M>::value, "");
+        static_assert(std::is_swappable_with<A&, A&>::value &&
+                      !std::is_nothrow_swappable_with<A&, A&>::value, "");
+    }
+    {
+        // test that hetrogenius swap is allowed only if both 'swap(A, B)' and
+        // 'swap(B, A)' are valid.
+        static_assert(std::is_nothrow_swappable_with<A&, B&>::value, "");
+        static_assert(!std::is_nothrow_swappable_with<A&, C&>::value &&
+                      std::is_swappable_with<A&, C&>::value, "");
+        static_assert(!std::is_nothrow_swappable_with<D&, C&>::value, "");
+    }
+    {
+        // test we guard against cv void inputs as required.
+        static_assert(!std::is_nothrow_swappable_with_v<void, int>);
+        static_assert(!std::is_nothrow_swappable_with_v<int, void>);
+        static_assert(!std::is_nothrow_swappable_with_v<const void, const volatile void>);
+
+    }
+    {
+        // test for presense of is_nothrow_swappable_with_v
+        static_assert(std::is_nothrow_swappable_with_v<int&, int&>);
+        static_assert(!std::is_nothrow_swappable_with_v<int&&, int&&>);
+    }
+}

Added: libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp?rev=267079&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable.pass.cpp Thu Apr 21 18:38:59 2016
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// type_traits
+
+// is_swappable
+
+#include <type_traits>
+#include <utility>
+#include <vector>
+#include "test_macros.h"
+
+namespace MyNS {
+
+// Make the test types non-copyable so that generic std::swap is not valid.
+struct A {
+  A(A const&) = delete;
+  A& operator=(A const&) = delete;
+};
+
+struct B {
+  B(B const&) = delete;
+  B& operator=(B const&) = delete;
+};
+
+struct C {};
+struct D {};
+
+void swap(A&, A&) {}
+
+void swap(A&, B&) {}
+void swap(B&, A&) {}
+
+void swap(A&, C&) {} // missing swap(C, A)
+void swap(D&, C&) {}
+
+struct M {
+  M(M const&) = delete;
+  M& operator=(M const&) = delete;
+};
+
+void swap(M&&, M&&) {}
+
+} // namespace MyNS
+
+int main()
+{
+    using namespace MyNS;
+    {
+        // Test that is_swappable applies an lvalue reference to the type.
+        static_assert(std::is_swappable<A>::value, "");
+        static_assert(std::is_swappable<A&>::value, "");
+        static_assert(!std::is_swappable<M>::value, "");
+        static_assert(!std::is_swappable<M&&>::value, "");
+    }
+    static_assert(!std::is_swappable<B>::value, "");
+    static_assert(std::is_swappable<C>::value, "");
+    {
+        // test non-referencable types
+        static_assert(!std::is_swappable<void>::value, "");
+        static_assert(!std::is_swappable<int() const>::value, "");
+        static_assert(!std::is_swappable<int() &>::value, "");
+    }
+    {
+        // test for presense of is_swappable_v
+        static_assert(std::is_swappable_v<int>);
+        static_assert(!std::is_swappable_v<M>);
+    }
+}

Added: libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp?rev=267079&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_include_order.pass.cpp Thu Apr 21 18:38:59 2016
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// type_traits
+
+// is_swappable
+
+// IMPORTANT: The include order is part of the test. We want to pick up
+// the following definitions in this order:
+//   1) is_swappable, is_nothrow_swappable
+//   2) iter_swap, swap_ranges
+//   3) swap(T (&)[N], T(&)[N]
+// This test checks that (1) and (2) see forward declarations
+// for (3).
+#include <type_traits>
+#include <algorithm>
+#include <utility>
+
+#include "test_macros.h"
+
+int main()
+{
+    // Use a builtin type so we don't get ADL lookup.
+    typedef double T[42][50];
+    {
+        static_assert(std::__is_swappable<T>::value, "");
+#if TEST_STD_VER > 14
+        static_assert(std::is_swappable_v<T>);
+#endif
+    }
+    {
+        T t1 = {};
+        T t2 = {};
+       std::iter_swap(t1, t2);
+       std::swap_ranges(t1, t1 + 42, t2);
+    }
+}

Added: libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp?rev=267079&view=auto
==============================================================================
--- libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp (added)
+++ libcxx/trunk/test/std/utilities/meta/meta.unary/meta.unary.prop/is_swappable_with.pass.cpp Thu Apr 21 18:38:59 2016
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// type_traits
+
+// is_swappable_with
+
+#include <type_traits>
+#include <vector>
+#include "test_macros.h"
+
+namespace MyNS {
+
+struct A {
+  A(A const&) = delete;
+  A& operator=(A const&) = delete;
+};
+
+struct B {
+  B(B const&) = delete;
+  B& operator=(B const&) = delete;
+};
+
+struct C {};
+struct D {};
+
+void swap(A&, A&) {}
+
+void swap(A&, B&) {}
+void swap(B&, A&) {}
+
+void swap(A&, C&) {} // missing swap(C, A)
+void swap(D&, C&) {}
+
+struct M {};
+
+void swap(M&&, M&&) {}
+
+} // namespace MyNS
+
+int main()
+{
+    using namespace MyNS;
+    {
+        // Test that is_swappable_with doesn't apply an lvalue reference
+        // to the type. Instead it is up to the user.
+        static_assert(!std::is_swappable_with<int, int>::value, "");
+        static_assert(std::is_swappable_with<int&, int&>::value, "");
+        static_assert(std::is_swappable_with<M, M>::value, "");
+        static_assert(std::is_swappable_with<A&, A&>::value, "");
+    }
+    {
+        // test that heterogeneous swap is allowed only if both 'swap(A, B)' and
+        // 'swap(B, A)' are valid.
+        static_assert(std::is_swappable_with<A&, B&>::value, "");
+        static_assert(!std::is_swappable_with<A&, C&>::value, "");
+        static_assert(!std::is_swappable_with<D&, C&>::value, "");
+    }
+    {
+        // test that cv void  is guarded against as required.
+        static_assert(!std::is_swappable_with_v<void, int>);
+        static_assert(!std::is_swappable_with_v<int, void>);
+        static_assert(!std::is_swappable_with_v<const void, const volatile void>);
+    }
+    {
+        // test for presence of is_swappable_with_v
+        static_assert(std::is_swappable_with_v<int&, int&>);
+        static_assert(!std::is_swappable_with_v<D&, C&>);
+    }
+}

Modified: libcxx/trunk/test/std/utilities/utility/utility.swap/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/utility/utility.swap/swap.pass.cpp?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/utility/utility.swap/swap.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/utility/utility.swap/swap.pass.cpp Thu Apr 21 18:38:59 2016
@@ -16,38 +16,88 @@
 
 #include <utility>
 #include <cassert>
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 #include <memory>
-#endif
-
-void
-test()
-{
-    int i = 1;
-    int j = 2;
-    std::swap(i, j);
-    assert(i == 2);
-    assert(j == 1);
-}
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#include "test_macros.h"
 
-void
-test1()
-{
-    std::unique_ptr<int> i(new int(1));
-    std::unique_ptr<int> j(new int(2));
-    std::swap(i, j);
-    assert(*i == 2);
-    assert(*j == 1);
+#if TEST_STD_VER >= 11
+struct CopyOnly {
+    CopyOnly() {}
+    CopyOnly(CopyOnly const&) noexcept {}
+    CopyOnly& operator=(CopyOnly const&) { return *this; }
+};
+
+struct MoveOnly {
+    MoveOnly() {}
+    MoveOnly(MoveOnly&&) {}
+    MoveOnly& operator=(MoveOnly&&) noexcept { return *this; }
+};
+
+struct NoexceptMoveOnly {
+    NoexceptMoveOnly() {}
+    NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
+    NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
+};
+
+struct NotMoveConstructible {
+    NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
+private:
+    NotMoveConstructible(NotMoveConstructible&&);
+};
+
+struct NotMoveAssignable {
+    NotMoveAssignable(NotMoveAssignable&&);
+private:
+    NotMoveAssignable& operator=(NotMoveAssignable&&);
+};
+
+template <class Tp>
+auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));
+
+template <class Tp>
+auto can_swap_test(...) -> std::false_type;
+
+template <class Tp>
+constexpr bool can_swap() {
+    return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
 }
-
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#endif
 
 int main()
 {
-    test();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    test1();
+
+    {
+        int i = 1;
+        int j = 2;
+        std::swap(i, j);
+        assert(i == 2);
+        assert(j == 1);
+    }
+#if TEST_STD_VER >= 11
+    {
+
+        std::unique_ptr<int> i(new int(1));
+        std::unique_ptr<int> j(new int(2));
+        std::swap(i, j);
+        assert(*i == 2);
+        assert(*j == 1);
+
+    }
+    {
+        // test that the swap
+        static_assert(can_swap<CopyOnly&>(), "");
+        static_assert(can_swap<MoveOnly&>(), "");
+        static_assert(can_swap<NoexceptMoveOnly&>(), "");
+
+        static_assert(!can_swap<NotMoveConstructible&>(), "");
+        static_assert(!can_swap<NotMoveAssignable&>(), "");
+
+        CopyOnly c;
+        MoveOnly m;
+        NoexceptMoveOnly nm;
+        static_assert(!noexcept(std::swap(c, c)), "");
+        static_assert(!noexcept(std::swap(m, m)), "");
+        static_assert(noexcept(std::swap(nm, nm)), "");
+    }
 #endif
 }

Modified: libcxx/trunk/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/utility/utility.swap/swap_array.pass.cpp?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/test/std/utilities/utility/utility.swap/swap_array.pass.cpp (original)
+++ libcxx/trunk/test/std/utilities/utility/utility.swap/swap_array.pass.cpp Thu Apr 21 18:38:59 2016
@@ -16,50 +16,86 @@
 
 #include <utility>
 #include <cassert>
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 #include <memory>
-#endif
 
-void
-test()
-{
-    int i[3] = {1, 2, 3};
-    int j[3] = {4, 5, 6};
-    std::swap(i, j);
-    assert(i[0] == 4);
-    assert(i[1] == 5);
-    assert(i[2] == 6);
-    assert(j[0] == 1);
-    assert(j[1] == 2);
-    assert(j[2] == 3);
-}
+#include "test_macros.h"
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-void
-test1()
-{
-    std::unique_ptr<int> i[3];
-    for (int k = 0; k < 3; ++k)
-        i[k].reset(new int(k+1));
-    std::unique_ptr<int> j[3];
-    for (int k = 0; k < 3; ++k)
-        j[k].reset(new int(k+4));
-    std::swap(i, j);
-    assert(*i[0] == 4);
-    assert(*i[1] == 5);
-    assert(*i[2] == 6);
-    assert(*j[0] == 1);
-    assert(*j[1] == 2);
-    assert(*j[2] == 3);
+#if TEST_STD_VER >= 11
+struct CopyOnly {
+    CopyOnly() {}
+    CopyOnly(CopyOnly const&) noexcept {}
+    CopyOnly& operator=(CopyOnly const&) { return *this; }
+};
+
+
+struct NoexceptMoveOnly {
+    NoexceptMoveOnly() {}
+    NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
+    NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
+};
+
+struct NotMoveConstructible {
+    NotMoveConstructible() {}
+    NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
+private:
+    NotMoveConstructible(NotMoveConstructible&&);
+};
+
+template <class Tp>
+auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));
+
+template <class Tp>
+auto can_swap_test(...) -> std::false_type;
+
+template <class Tp>
+constexpr bool can_swap() {
+    return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
 }
+#endif
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
 int main()
 {
-    test();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-    test1();
+    {
+        int i[3] = {1, 2, 3};
+        int j[3] = {4, 5, 6};
+        std::swap(i, j);
+        assert(i[0] == 4);
+        assert(i[1] == 5);
+        assert(i[2] == 6);
+        assert(j[0] == 1);
+        assert(j[1] == 2);
+        assert(j[2] == 3);
+    }
+#if TEST_STD_VER >= 11
+    {
+        std::unique_ptr<int> i[3];
+        for (int k = 0; k < 3; ++k)
+            i[k].reset(new int(k+1));
+        std::unique_ptr<int> j[3];
+        for (int k = 0; k < 3; ++k)
+            j[k].reset(new int(k+4));
+        std::swap(i, j);
+        assert(*i[0] == 4);
+        assert(*i[1] == 5);
+        assert(*i[2] == 6);
+        assert(*j[0] == 1);
+        assert(*j[1] == 2);
+        assert(*j[2] == 3);
+    }
+    {
+        using CA = CopyOnly[42];
+        using MA = NoexceptMoveOnly[42];
+        using NA = NotMoveConstructible[42];
+        static_assert(can_swap<CA&>(), "");
+        static_assert(can_swap<MA&>(), "");
+        static_assert(!can_swap<NA&>(), "");
+
+        CA ca;
+        MA ma;
+        static_assert(!noexcept(std::swap(ca, ca)), "");
+        static_assert(noexcept(std::swap(ma, ma)), "");
+    }
 #endif
 }

Modified: libcxx/trunk/www/cxx1z_status.html
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx1z_status.html?rev=267079&r1=267078&r2=267079&view=diff
==============================================================================
--- libcxx/trunk/www/cxx1z_status.html (original)
+++ libcxx/trunk/www/cxx1z_status.html Thu Apr 21 18:38:59 2016
@@ -85,7 +85,7 @@
 	<tr><td><a href="http://wg21.link/P0033R1">P0033R1</a></td><td>LWG</td><td>Re-enabling shared_from_this</td><td>Jacksonville</td><td></td><td></td></tr>
 	<tr><td><a href="http://wg21.link/P0005R4">P0005R4</a></td><td>LWG</td><td>Adopt not_fn from Library Fundamentals 2 for C++17</td><td>Jacksonville</td><td></td><td></td></tr>
 	<tr><td><a href="http://wg21.link/P0152R1">P0152R1</a></td><td>LWG</td><td>constexpr atomic::is_always_lock_free</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
-	<tr><td><a href="http://wg21.link/P0185R1">P0185R1</a></td><td>LWG</td><td>Adding [nothrow-]swappable traits</td><td>Jacksonville</td><td></td><td></td></tr>
+	<tr><td><a href="http://wg21.link/P0185R1">P0185R1</a></td><td>LWG</td><td>Adding [nothrow-]swappable traits</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
 	<tr><td><a href="http://wg21.link/P0253R1">P0253R1</a></td><td>LWG</td><td>Fixing a design mistake in the searchers interface</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
 	<tr><td><a href="http://wg21.link/P0025R0">P0025R0</a></td><td>LWG</td><td>An algorithm to "clamp" a value between a pair of boundary values</td><td>Jacksonville</td><td>Complete</td><td>3.9</td></tr>
 	<tr><td><a href="http://wg21.link/P0154R1">P0154R1</a></td><td>LWG</td><td>constexpr std::hardware_{constructive,destructive}_interference_size</td><td>Jacksonville</td><td></td><td></td></tr>




More information about the cfe-commits mailing list