[libcxx-commits] [libcxx] [libc++] P3612R1: Harmonize proxy-reference operations (PR #173710)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Dec 27 01:11:09 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: A. Jiang (frederick-vs-ja)
<details>
<summary>Changes</summary>
Implements it as a Defect Report against C++03 except for the deprecation.
Fixes #<!-- -->171281.
---
Patch is 23.61 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/173710.diff
11 Files Affected:
- (modified) libcxx/docs/ReleaseNotes/22.rst (+1)
- (modified) libcxx/docs/Status/Cxx2cPapers.csv (+1-1)
- (modified) libcxx/include/__bit_reference (+17-30)
- (modified) libcxx/include/__vector/vector_bool.h (+5-2)
- (modified) libcxx/include/bitset (+11-8)
- (modified) libcxx/include/vector (+10-5)
- (added) libcxx/test/std/containers/sequences/vector.bool/reference.swap.deprecated.verify.cpp (+37)
- (modified) libcxx/test/std/containers/sequences/vector.bool/reference.swap.pass.cpp (+2)
- (modified) libcxx/test/std/containers/sequences/vector.bool/swap.pass.cpp (+121-16)
- (modified) libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp (+43-25)
- (added) libcxx/test/std/utilities/template.bitset/bitset.members/reference.swap.pass.cpp (+111)
``````````diff
diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index 0d1a1fbc00f2c..8883ae5e48be7 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -52,6 +52,7 @@ Implemented Papers
- P2944R3: Comparisons for ``reference_wrapper`` (`Github <https://llvm.org/PR105424>`__)
- P3168R2: Give ``std::optional`` Range Support (`Github <https://llvm.org/PR105430>`__)
- P3567R2: ``flat_meow`` Fixes (`Github <https://llvm.org/PR162022>`__)
+- P3612R1: Harmonize proxy-reference operations (LWG 3638 and 4187) (`Github <https://llvm.org/PR171281>`__)
- P3836R2: Make ``optional<T&>`` trivially copyable (`Github <https://llvm.org/PR171275>`__)
- P1789R3: Library Support for Expansion Statements (`Github <https://llvm.org/PR167184>`__)
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 9bb5d2bda3d4d..9c398139ff7a1 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -167,7 +167,7 @@
"`P3388R3 <https://wg21.link/P3388R3>`__","When Do You Know ``connect`` Doesn’t Throw?","2025-11 (Kona)","","","`#171277 <https://github.com/llvm/llvm-project/issues/171277>`__",""
"`P3774R1 <https://wg21.link/P3774R1>`__","Rename ``std::nontype``, and make it broadly useful","2025-11 (Kona)","","","`#171279 <https://github.com/llvm/llvm-project/issues/171279>`__",""
"`P3819R0 <https://wg21.link/P3819R0>`__","Remove ``evaluation_exception()`` from contract-violation handling for C++26","2025-11 (Kona)","","","`#171280 <https://github.com/llvm/llvm-project/issues/171280>`__",""
-"`P3612R1 <https://wg21.link/P3612R1>`__","Harmonize proxy-reference operations (LWG 3638 and 4187)","2025-11 (Kona)","","","`#171281 <https://github.com/llvm/llvm-project/issues/171281>`__",""
+"`P3612R1 <https://wg21.link/P3612R1>`__","Harmonize proxy-reference operations (LWG 3638 and 4187)","2025-11 (Kona)","|Complete|","22","`#171281 <https://github.com/llvm/llvm-project/issues/171281>`__","Implemented as a DR against C++03 except for the deprecation."
"`P3778R0 <https://wg21.link/P3778R0>`__","Fix for ``type_order`` template definition","2025-11 (Kona)","","","`#171284 <https://github.com/llvm/llvm-project/issues/171284>`__",""
"`P1789R3 <https://wg21.link/P1789R3>`__","Library Support for Expansion Statements","2025-11 (Kona)","|Complete|","22","`#167268 <https://github.com/llvm/llvm-project/issues/167268>`__",""
"`P3922R1 <https://wg21.link/P3922R1>`__","Missing deduction guide from ``simd::mask`` to ``simd::vec``","2025-11 (Kona)","","","`#171285 <https://github.com/llvm/llvm-project/issues/171285>`__",""
diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference
index 8daf3a2baafcd..f80ce9fcf8ea6 100644
--- a/libcxx/include/__bit_reference
+++ b/libcxx/include/__bit_reference
@@ -170,6 +170,23 @@ public:
return __bit_iterator<_Cp, false>(__seg_, static_cast<unsigned>(std::__countr_zero(__mask_)));
}
+ _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR_SINCE_CXX20 void
+ swap(__bit_reference __x, __bit_reference __y) _NOEXCEPT {
+ bool __t = __x;
+ __x = __y;
+ __y = __t;
+ }
+ _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference __x, bool& __y) _NOEXCEPT {
+ bool __t = __x;
+ __x = __y;
+ __y = __t;
+ }
+ _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(bool& __x, __bit_reference __y) _NOEXCEPT {
+ bool __t = __x;
+ __x = __y;
+ __y = __t;
+ }
+
private:
_LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT
@@ -180,36 +197,6 @@ private:
template <class _Cp>
class __bit_reference<_Cp, false> {};
-template <class _Cp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
-swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT {
- bool __t = __x;
- __x = __y;
- __y = __t;
-}
-
-template <class _Cp, class _Dp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
-swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT {
- bool __t = __x;
- __x = __y;
- __y = __t;
-}
-
-template <class _Cp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT {
- bool __t = __x;
- __x = __y;
- __y = __t;
-}
-
-template <class _Cp>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT {
- bool __t = __x;
- __x = __y;
- __y = __t;
-}
-
template <class _Cp>
class __bit_const_reference {
using __storage_type _LIBCPP_NODEBUG = typename _Cp::__storage_type;
diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index f81fcd92a7e49..0483db569df46 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -398,8 +398,11 @@ class vector<bool, _Allocator> {
#else
_NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<allocator_type>);
#endif
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void swap(reference __x, reference __y) _NOEXCEPT {
- std::swap(__x, __y);
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX26
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 static void swap(reference __x, reference __y) _NOEXCEPT {
+ bool __t = __x;
+ __x = __y;
+ __y = __t;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void resize(size_type __sz, value_type __x = false);
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index 37253f5722389..c7e56ced1c41f 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -27,15 +27,18 @@ public:
// bit reference:
class reference
{
- friend class bitset;
- reference() noexcept;
public:
- ~reference() noexcept;
- reference& operator=(bool x) noexcept; // for b[i] = x;
- reference& operator=(const reference&) noexcept; // for b[i] = b[j];
- bool operator~() const noexcept; // flips the bit
- operator bool() const noexcept; // for x = b[i];
- reference& flip() noexcept; // for b[i].flip();
+ reference(const reference& x) noexcept; // constexpr since C++23
+ ~reference() noexcept; // constexpr since C++23
+ reference& operator=(bool x) noexcept; // constexpr since C++23; for b[i] = x;
+ reference& operator=(const reference&) noexcept; // constexpr since C++23; for b[i] = b[j];
+ constexpr reference& operator=(bool x) const noexcept; // since C++23
+ bool operator~() const noexcept; // constexpr since C++23; flips the bit
+ operator bool() const noexcept; // constexpr since C++23; for x = b[i];
+ void flip() noexcept; // constexpr since C++23; for b[i].flip();
+ friend void swap(reference x, reference y) noexcept; // constexpr since C++23
+ friend void swap(reference x, bool& y) noexcept; // constexpr since C++23
+ friend void swap(bool& x, reference y) noexcept; // constexpr since C++23
};
// 23.3.5.1 constructors:
diff --git a/libcxx/include/vector b/libcxx/include/vector
index d2d5fcf4a3199..37b75f1619e53 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -152,12 +152,16 @@ public:
class reference
{
public:
- reference(const reference&) noexcept;
- operator bool() const noexcept;
- reference& operator=(bool x) noexcept;
- reference& operator=(const reference& x) noexcept;
+ reference(const reference&) noexcept; // constexpr since C++20
+ operator bool() const noexcept; // constexpr since C++20
+ reference& operator=(bool x) noexcept; // constexpr since C++20
+ reference& operator=(const reference& x) noexcept; // constexpr since C++20
+ constexpr reference& operator=(bool x) const noexcept; // since C++23
iterator operator&() const noexcept;
- void flip() noexcept;
+ void flip() noexcept; // constexpr since C++20
+ friend void swap(reference x, reference y) noexcept; // constexpr since C++20
+ friend void swap(reference x, bool& y) noexcept; // constexpr since C++20
+ friend void swap(bool& x, reference y) noexcept; // constexpr since C++20
};
class const_reference
@@ -255,6 +259,7 @@ public:
void swap(vector&)
noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value ||
allocator_traits<allocator_type>::is_always_equal::value); // C++17
+ static void swap(reference x, reference, y) noexcept; // deprecated in C++26
void flip() noexcept;
bool __invariants() const;
diff --git a/libcxx/test/std/containers/sequences/vector.bool/reference.swap.deprecated.verify.cpp b/libcxx/test/std/containers/sequences/vector.bool/reference.swap.deprecated.verify.cpp
new file mode 100644
index 0000000000000..b8259c63b954b
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/reference.swap.deprecated.verify.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// <vector>
+
+// vector<bool>;
+// static void swap(reference x, reference y) noexcept; // deprecated in C++26
+
+#include <vector>
+
+#include "test_macros.h"
+#include "min_allocator.h"
+
+void test() {
+ {
+ using VB = std::vector<bool>;
+ VB vb(2);
+ VB::swap(vb[0], vb[1]); // expected-warning {{'swap' is deprecated}}
+ }
+ {
+ using VB = std::vector<bool, min_allocator<bool>>;
+ VB vb(2);
+ VB::swap(vb[0], vb[1]); // expected-warning {{'swap' is deprecated}}
+ }
+ {
+ using VB = std::pmr::vector<bool>;
+ VB vb(2);
+ VB::swap(vb[0], vb[1]); // expected-warning {{'swap' is deprecated}}
+ }
+}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/reference.swap.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/reference.swap.pass.cpp
index a0476b6fc305b..875c5224e833b 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/reference.swap.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/reference.swap.pass.cpp
@@ -11,6 +11,8 @@
// static void swap(reference x, reference y) noexcept;
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
#include <vector>
#include <cassert>
diff --git a/libcxx/test/std/containers/sequences/vector.bool/swap.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/swap.pass.cpp
index 9b29a245e389a..132c82c54903d 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/swap.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/swap.pass.cpp
@@ -11,14 +11,49 @@
// void swap(vector& x);
+// class reference;
+// friend void swap(reference x, reference y);
+// friend void swap(reference x, bool&);
+// friend void swap(bool& x, reference y);
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
#include <vector>
#include <cassert>
+#include <type_traits>
+#include <utility>
+
#include "test_macros.h"
#include "test_allocator.h"
#include "min_allocator.h"
-TEST_CONSTEXPR_CXX20 bool tests() {
+template <class T, class U, class = void>
+struct can_qualified_std_swap_with : std::false_type {};
+template <class T, class U>
+struct can_qualified_std_swap_with<T, U, decltype((void)std::swap(std::declval<T>(), std::declval<U>()))>
+ : std::true_type {};
+
+template <class T>
+struct can_qualified_std_swap : can_qualified_std_swap_with<T&, T&>::type {};
+
+namespace adl_only {
+void swap();
+
+template <class T, class U, class = void>
+struct can_swap_with : std::false_type {};
+template <class T, class U>
+struct can_swap_with<T, U, decltype((void)swap(std::declval<T>(), std::declval<U>()))> : std::true_type {};
+
+template <class T>
+struct can_swap : can_swap_with<T&, T&>::type {};
+} // namespace adl_only
+
+TEST_CONSTEXPR_CXX20 void test_vector_bool_swap() {
{
+ typedef std::vector<bool> VB;
+ static_assert(can_qualified_std_swap<VB>::value, "");
+ static_assert(adl_only::can_swap<VB>::value, "");
+
std::vector<bool> v1(100);
std::vector<bool> v2(200);
v1.swap(v2);
@@ -29,6 +64,10 @@ TEST_CONSTEXPR_CXX20 bool tests() {
}
{
typedef test_allocator<bool> A;
+ typedef std::vector<bool, A> VB;
+ static_assert(can_qualified_std_swap<VB>::value, "");
+ static_assert(adl_only::can_swap<VB>::value, "");
+
std::vector<bool, A> v1(100, true, A(1, 1));
std::vector<bool, A> v2(200, false, A(1, 2));
swap(v1, v2);
@@ -41,6 +80,10 @@ TEST_CONSTEXPR_CXX20 bool tests() {
}
{
typedef other_allocator<bool> A;
+ typedef std::vector<bool, A> VB;
+ static_assert(can_qualified_std_swap<VB>::value, "");
+ static_assert(adl_only::can_swap<VB>::value, "");
+
std::vector<bool, A> v1(100, true, A(1));
std::vector<bool, A> v2(200, false, A(2));
swap(v1, v2);
@@ -51,18 +94,13 @@ TEST_CONSTEXPR_CXX20 bool tests() {
assert(v1.get_allocator() == A(2));
assert(v2.get_allocator() == A(1));
}
- {
- std::vector<bool> v(2);
- std::vector<bool>::reference r1 = v[0];
- std::vector<bool>::reference r2 = v[1];
- r1 = true;
- using std::swap;
- swap(r1, r2);
- assert(v[0] == false);
- assert(v[1] == true);
- }
#if TEST_STD_VER >= 11
{
+ using A = min_allocator<bool>;
+ using VB = std::vector<bool, A>;
+ static_assert(can_qualified_std_swap<VB>::value, "");
+ static_assert(adl_only::can_swap<VB>::value, "");
+
std::vector<bool, min_allocator<bool>> v1(100);
std::vector<bool, min_allocator<bool>> v2(200);
v1.swap(v2);
@@ -72,7 +110,7 @@ TEST_CONSTEXPR_CXX20 bool tests() {
assert(v2.capacity() >= 100);
}
{
- typedef min_allocator<bool> A;
+ using A = min_allocator<bool>;
std::vector<bool, A> v1(100, true, A());
std::vector<bool, A> v2(200, false, A());
swap(v1, v2);
@@ -83,18 +121,85 @@ TEST_CONSTEXPR_CXX20 bool tests() {
assert(v1.get_allocator() == A());
assert(v2.get_allocator() == A());
}
+#endif
+}
+
+TEST_CONSTEXPR_CXX20 void test_vector_bool_reference_swap() {
+ { // Test that only homogeneous vector<bool, A>::reference swap is supported.
+ typedef std::vector<bool>::reference VBRef1;
+ typedef std::vector<bool, test_allocator<bool> >::reference VBRef2;
+ static_assert(can_qualified_std_swap_with<VBRef1, VBRef2>::value == std::is_same<VBRef1, VBRef2>::value, "");
+ static_assert(adl_only::can_swap_with<VBRef1, VBRef2>::value == std::is_same<VBRef1, VBRef2>::value, "");
+ }
{
- std::vector<bool, min_allocator<bool>> v(2);
- std::vector<bool, min_allocator<bool>>::reference r1 = v[0];
- std::vector<bool, min_allocator<bool>>::reference r2 = v[1];
- r1 = true;
+ typedef std::vector<bool>::reference VBRef;
+ static_assert(can_qualified_std_swap<VBRef>::value, "");
+ static_assert(!can_qualified_std_swap_with<VBRef, VBRef>::value, "");
+ static_assert(!can_qualified_std_swap_with<VBRef, bool&>::value, "");
+ static_assert(!can_qualified_std_swap_with<bool&, VBRef>::value, "");
+ static_assert(adl_only::can_swap<VBRef>::value, "");
+ static_assert(adl_only::can_swap_with<VBRef, VBRef>::value, "");
+ static_assert(adl_only::can_swap_with<VBRef, bool&>::value, "");
+ static_assert(adl_only::can_swap_with<bool&, VBRef>::value, "");
+
+ using std::swap;
+
+ std::vector<bool> v(2);
+ VBRef r1 = v[0];
+ VBRef r2 = v[1];
+ r1 = true;
+
+ swap(r1, r2);
+ assert(v[0] == false);
+ assert(v[1] == true);
+
+ bool b1 = true;
+ swap(r1, b1);
+ assert(v[0] == true);
+ assert(b1 == false);
+
+ swap(b1, r1);
+ assert(v[0] == false);
+ assert(b1 == true);
+ }
+#if TEST_STD_VER >= 11
+ {
+ using VBRef = std::vector<bool, min_allocator<bool>>::reference;
+ static_assert(can_qualified_std_swap<VBRef>::value, "");
+ static_assert(!can_qualified_std_swap_with<VBRef, VBRef>::value, "");
+ static_assert(!can_qualified_std_swap_with<VBRef, bool&>::value, "");
+ static_assert(!can_qualified_std_swap_with<bool&, VBRef>::value, "");
+ static_assert(adl_only::can_swap<VBRef>::value, "");
+ static_assert(adl_only::can_swap_with<VBRef, VBRef>::value, "");
+ static_assert(adl_only::can_swap_with<VBRef, bool&>::value, "");
+ static_assert(adl_only::can_swap_with<bool&, VBRef>::value, "");
+
using std::swap;
+
+ std::vector<bool, min_allocator<bool>> v(2);
+ VBRef r1 = v[0];
+ VBRef r2 = v[1];
+ r1 = true;
+
swap(r1, r2);
assert(v[0] == false);
assert(v[1] == true);
+
+ bool b1 = true;
+ swap(r1, b1);
+ assert(v[0] == true);
+ assert(b1 == false);
+
+ swap(b1, r1);
+ assert(v[0] == false);
+ assert(b1 == true);
}
#endif
+}
+TEST_CONSTEXPR_CXX20 bool tests() {
+ test_vector_bool_swap();
+ test_vector_bool_reference_swap();
return true;
}
diff --git a/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp
index 8d3aeca7da3c6..34ea2ac0a4496 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp
@@ -12,38 +12,56 @@
#include <cassert>
#include <cstddef>
#include <vector>
+#include <type_traits>
#include "../bitset_test_cases.h"
#include "test_macros.h"
template <std::size_t N>
TEST_CONSTEXPR_CXX23 void test_index() {
- std::vector<std::bitset<N> > const cases = get_test_cases<N>();
- for (std::size_t c = 0; c != cases.size(); ++c) {
- std::bitset<N> v1 = cases[c];
- if (v1.size() > 0) {
- assert(v1[N/2] == v1.test(N/2));
- typename std::bitset<N>::reference r = v1[N/2];
- assert(r == v1.test(N/2));
- typename std::bitset<N>::reference r2 = v1[N/2];
- r = r2;
- assert(r == v1.test(N/2));
- r = false;
- assert(r == false);
- assert(v1.test(N/2) == false);
- r = true;
- assert(r == true);
- assert(v1.test(N/2) == true);
- bool b = ~r;
- assert(r == true);
- assert(v1.test(N/2) == true);
- assert(b == false);
- r.flip();
- assert(r == false);
- assert(v1.test(N/2) == false);
- }
- ASSERT_SAME_TYPE(decltype(v1[0]), typename std::bitset<N>::reference);
+ typedef typename std::bitset<N>::reference BRef;
+#if TEST_STD_VER >= 23
+ static_assert(std::is_assignable_v<const BRef, bool>);
+#else
+ static_assert(!std::is_assignable<const BRef, bool>::value, "");
+#endif
+
+ std::vector<std::bitset<N> > const cases = get_test_cases<N>();
+ for (std::size_t c = 0; c != cases.size(); ++c) {
+ std::bitset<N> v1 = cases[c];
+ if (v1.size() > 0) {
+ assert(v1[N / 2] == v1.test(N / 2));
+ BRef r = v1[N / 2];
+ assert(r == v1.test(N / 2));
+ BRef r2 = v1[N / 2];
+ r = r2;
+ assert(r == v1.test(N / 2));
+ r = false;
+ assert(r == false);
+ assert(v1.test(N / 2) == false);
+ r = true;
+ assert(r == true);
+ assert(v1.test(N / 2) == true);
+ bool b = ~r;
+ assert(r == true);
+ assert(v1.test(N / 2) == true);
+ assert(b == false);
+ r.flip();
+ assert(r == false);
+ assert(v1.test(N / 2) == false);
+
+#if TEST_STD_VER >= 23
+ const auto& cr = r;
+ decltype(auto) cr2 = (cr = true);
+ ASSERT_SAME_TYPE(decltype(cr2), const BRef&);
+ ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/173710
More information about the libcxx-commits
mailing list