[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
This commit is contained in:
parent
a547b4e26b
commit
cedd07df51
@ -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|",""
|
||||
|
||||
|
@ -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));
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user