[libcxx-commits] [PATCH] D111481: [libc++] P2401: conditional noexcept for std::exchange

Joe Loser via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Oct 8 20:28:48 PDT 2021


jloser created this revision.
jloser added reviewers: ldionne, Quuxplusone, Mordante.
jloser requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

Implement P2401 <https://reviews.llvm.org/P2401> which adds a `noexcept` specification to
`std::exchange`. Treated as a defect fix which is the motivation for
applying this change to all standards mode rather than just C++23 or
later as the paper suggests.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111481

Files:
  libcxx/docs/Status/Cxx2bPapers.csv
  libcxx/include/__utility/exchange.h
  libcxx/test/std/utilities/utility/exchange/exchange.pass.cpp


Index: libcxx/test/std/utilities/utility/exchange/exchange.pass.cpp
===================================================================
--- libcxx/test/std/utilities/utility/exchange/exchange.pass.cpp
+++ libcxx/test/std/utilities/utility/exchange/exchange.pass.cpp
@@ -18,6 +18,7 @@
 #include <utility>
 #include <cassert>
 #include <string>
+#include <type_traits>
 
 #include "test_macros.h"
 
@@ -37,6 +38,31 @@
     }
 #endif
 
+template<bool Move, bool Assign>
+struct TestExchangeNoexcept{
+  TestExchangeNoexcept() = default;
+  TestExchangeNoexcept(TestExchangeNoexcept&&) noexcept(Move);
+  void operator=(const TestExchangeNoexcept&) noexcept(Assign);
+};
+
+constexpr bool test_noexcept() {
+  int v = 42;
+  static_assert(std::is_nothrow_move_constructible_v<int>);
+  static_assert(std::is_nothrow_assignable_v<int&, int>);
+  ASSERT_NOEXCEPT(std::exchange(v, {}));
+
+  TestExchangeNoexcept<true, false> nothrow_move_constructible{};
+  static_assert(std::is_nothrow_move_constructible_v<decltype(nothrow_move_constructible)>);
+  static_assert(!std::is_nothrow_assignable_v<decltype(nothrow_move_constructible)&, decltype(nothrow_move_constructible)>);
+  ASSERT_NOT_NOEXCEPT(std::exchange(nothrow_move_constructible, {}));
+
+  TestExchangeNoexcept<false, true> nothrow_assignable{};
+  static_assert(!std::is_nothrow_move_constructible_v<decltype(nothrow_assignable)>);
+  static_assert(std::is_nothrow_assignable_v<decltype(nothrow_assignable)&, decltype(nothrow_assignable)>);
+  ASSERT_NOT_NOEXCEPT(std::exchange(nothrow_assignable, {}));
+
+  return true;
+}
 
 
 int main(int, char**)
@@ -81,5 +107,8 @@
     static_assert(test_constexpr());
 #endif
 
+    test_noexcept();
+    static_assert(test_noexcept());
+
   return 0;
 }
Index: libcxx/include/__utility/exchange.h
===================================================================
--- libcxx/include/__utility/exchange.h
+++ libcxx/include/__utility/exchange.h
@@ -12,6 +12,7 @@
 #include <__config>
 #include <__utility/forward.h>
 #include <__utility/move.h>
+#include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -22,7 +23,7 @@
 #if _LIBCPP_STD_VER > 11
 template<class _T1, class _T2 = _T1>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
-_T1 exchange(_T1& __obj, _T2 && __new_value)
+_T1 exchange(_T1& __obj, _T2 && __new_value) noexcept(is_nothrow_move_constructible_v<_T1> && is_nothrow_assignable_v<_T1&, _T2>)
 {
     _T1 __old_value = _VSTD::move(__obj);
     __obj = _VSTD::forward<_T2>(__new_value);
Index: libcxx/docs/Status/Cxx2bPapers.csv
===================================================================
--- libcxx/docs/Status/Cxx2bPapers.csv
+++ libcxx/docs/Status/Cxx2bPapers.csv
@@ -36,5 +36,5 @@
 "`P2321 <https://wg21.link/P2321>`__","LWG","``zip``","October 2021","",""
 "`P2340 <https://wg21.link/P2340>`__","LWG","Clarifying the status of the 'C headers'","October 2021","",""
 "`P2393 <https://wg21.link/P2393>`__","LWG","Cleaning up ``integer``-class types","October 2021","",""
-"`P2401 <https://wg21.link/P2401>`__","LWG","Add a conditional ``noexcept`` specification to ``std::exchange``","October 2021","",""
+"`P2401 <https://wg21.link/P2401>`__","LWG","Add a conditional ``noexcept`` specification to ``std::exchange``","October 2021","Complete","14.0"
 "","","","","",""


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D111481.378407.patch
Type: text/x-patch
Size: 3357 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211009/4979aad5/attachment.bin>


More information about the libcxx-commits mailing list