[libcxx-commits] [libcxx] cedd07d - [libcxx] fixes `common_reference` requirement for `swappable_with`

Christopher Di Bella via libcxx-commits libcxx-commits at lists.llvm.org
Tue Apr 6 22:51:52 PDT 2021


Author: Christopher Di Bella
Date: 2021-04-07T05:51:36Z
New Revision: cedd07df5136ba446be23dbd2ca7d29d7b82cd60

URL: https://github.com/llvm/llvm-project/commit/cedd07df5136ba446be23dbd2ca7d29d7b82cd60
DIFF: https://github.com/llvm/llvm-project/commit/cedd07df5136ba446be23dbd2ca7d29d7b82cd60.diff

LOG: [libcxx] fixes `common_reference` requirement for `swappable_with`

LWG3175 identifies that the `common_reference` requirement for
`swappable_with` is over-constraining and doesn't need to concern itself
with cv- or reference qualifiers.

Differential Revision: https://reviews.llvm.org/D99817

Added: 
    

Modified: 
    libcxx/docs/Cxx2aStatusIssuesStatus.csv
    libcxx/include/concepts
    libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable_with.compile.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Cxx2aStatusIssuesStatus.csv b/libcxx/docs/Cxx2aStatusIssuesStatus.csv
index 064adf29df333..55d5126ab2930 100644
--- a/libcxx/docs/Cxx2aStatusIssuesStatus.csv
+++ b/libcxx/docs/Cxx2aStatusIssuesStatus.csv
@@ -194,7 +194,7 @@
 "`3050 <https://wg21.link/LWG3050>`__","Conversion specification problem in ``chrono::duration``\  constructor","Prague","",""
 "`3141 <https://wg21.link/LWG3141>`__","``CopyConstructible``\  doesn't preserve source values","Prague","",""
 "`3150 <https://wg21.link/LWG3150>`__","``UniformRandomBitGenerator``\  should validate ``min``\  and ``max``\ ","Prague","",""
-"`3175 <https://wg21.link/LWG3175>`__","The ``CommonReference``\  requirement of concept ``SwappableWith``\  is not satisfied in the example","Prague","",""
+"`3175 <https://wg21.link/LWG3175>`__","The ``CommonReference``\  requirement of concept ``SwappableWith``\  is not satisfied in the example","Prague","|Complete|","13.0"
 "`3194 <https://wg21.link/LWG3194>`__","``ConvertibleTo``\  prose does not match code","Prague","",""
 "`3200 <https://wg21.link/LWG3200>`__","``midpoint``\  should not constrain ``T``\  is complete","Prague","|Nothing To Do|",""
 "`3201 <https://wg21.link/LWG3201>`__","``lerp``\  should be marked as ``noexcept``\ ","Prague","|Complete|",""

diff  --git a/libcxx/include/concepts b/libcxx/include/concepts
index 200a17795f9a2..6ce2fad1426b9 100644
--- a/libcxx/include/concepts
+++ b/libcxx/include/concepts
@@ -326,7 +326,7 @@ concept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); };
 
 template<class _Tp, class _Up>
 concept swappable_with =
-  common_reference_with<_Tp&, _Up&> &&
+  common_reference_with<_Tp, _Up> &&
   requires(_Tp&& __t, _Up&& __u) {
     ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t));
     ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u));

diff  --git a/libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable_with.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable_with.compile.pass.cpp
index 46e526dcd0c82..e0772b51d8187 100644
--- a/libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable_with.compile.pass.cpp
+++ b/libcxx/test/std/concepts/concepts.lang/concept.swappable/swappable_with.compile.pass.cpp
@@ -15,6 +15,7 @@
 #include <concepts>
 
 #include <array>
+#include <cassert>
 #include <deque>
 #include <forward_list>
 #include <list>
@@ -555,7 +556,7 @@ struct swappable_with_rvalue_ref_to_volatile_s3 {
   friend void swap(swappable_with_rvalue_ref_to_volatile_s3 volatile&&,
                    s3 volatile&&);
 
-  operator s3 volatile &() volatile;
+  operator s3 volatile &&() volatile;
 };
 static_assert(
     std::swappable_with<swappable_with_rvalue_ref_to_volatile_s3 volatile&&,
@@ -578,7 +579,7 @@ struct swappable_with_rvalue_ref_to_cv_s3 {
   friend void swap(swappable_with_rvalue_ref_to_cv_s3 const volatile&&,
                    s3 const volatile&&);
 
-  operator s3 const volatile &() const volatile;
+  operator s3 const volatile &&() const volatile;
 };
 static_assert(
     std::swappable_with<swappable_with_rvalue_ref_to_cv_s3 const volatile&&,
@@ -644,4 +645,42 @@ static_assert(
 static_assert(!check_swappable_with<HasANonMovable, HasANonMovable>());
 } // namespace types_with_purpose
 
-int main(int, char**) { return 0; }
+namespace LWG3175 {
+// Example taken directly from [concept.swappable]
+template <class T, std::swappable_with<T> U>
+constexpr void value_swap(T&& t, U&& u) {
+  std::ranges::swap(std::forward<T>(t), std::forward<U>(u));
+}
+
+template <std::swappable T>
+constexpr void lv_swap(T& t1, T& t2) {
+  std::ranges::swap(t1, t2);
+}
+
+namespace N {
+struct A {
+  int m;
+};
+struct Proxy {
+  A* a;
+  constexpr Proxy(A& a_) : a{&a_} {}
+  friend constexpr void swap(Proxy x, Proxy y) {
+    std::ranges::swap(*x.a, *y.a);
+  }
+};
+constexpr Proxy proxy(A& a) { return Proxy{a}; }
+} // namespace N
+
+[[nodiscard]] constexpr bool CheckRegression() {
+  int i = 1, j = 2;
+  lv_swap(i, j);
+  assert(i == 2 && j == 1);
+
+  N::A a1 = {5}, a2 = {-5};
+  value_swap(a1, proxy(a2));
+  assert(a1.m == -5 && a2.m == 5);
+  return true;
+}
+
+static_assert(CheckRegression());
+} // namespace LWG3175


        


More information about the libcxx-commits mailing list