[libcxx-commits] [libcxx] 56379b2 - Simplify flip() for std::bitset (#120807)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Feb 26 06:34:00 PST 2025
Author: Peng Liu
Date: 2025-02-26T15:33:57+01:00
New Revision: 56379b29042db9dfc63e74f065cc50b7fb01eddf
URL: https://github.com/llvm/llvm-project/commit/56379b29042db9dfc63e74f065cc50b7fb01eddf
DIFF: https://github.com/llvm/llvm-project/commit/56379b29042db9dfc63e74f065cc50b7fb01eddf.diff
LOG: Simplify flip() for std::bitset (#120807)
This PR simplifies the internal bitwise logic of the `flip()` function
for `std::bitset`.
Added:
Modified:
libcxx/include/bitset
libcxx/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp
libcxx/test/std/utilities/template.bitset/bitset_test_cases.h
Removed:
################################################################################
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index ab1dda739c7d5..d9acc326106d2 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -329,12 +329,10 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<_N_words, _Siz
for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
*__p = ~*__p;
// do last partial word
- if (__n > 0) {
- __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
- __storage_type __b = *__p & __m;
- *__p &= ~__m;
- *__p |= ~__b & __m;
- }
+ // Ensure trailing padding bits are zeroed as part of the ABI for consistent hashing behavior. std::hash<bitset>
+ // assumes trailing bits are zeroed; otherwise, identical bitsets could hash
diff erently.
+ if (__n > 0)
+ *__p ^= (__storage_type(1) << __n) - 1;
}
template <size_t _N_words, size_t _Size>
@@ -514,9 +512,7 @@ __bitset<1, _Size>::operator^=(const __bitset& __v) _NOEXCEPT {
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Size>::flip() _NOEXCEPT {
- __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
- __first_ = ~__first_;
- __first_ &= __m;
+ __first_ ^= ~__storage_type(0) >> (__bits_per_word - _Size);
}
template <size_t _Size>
diff --git a/libcxx/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp
index 79fa505e63cd3..55401367cd08f 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp
@@ -18,19 +18,21 @@
template <std::size_t N>
TEST_CONSTEXPR_CXX23 void test_flip_all() {
- 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];
- std::bitset<N> v2 = v1;
- v2.flip();
- for (std::size_t i = 0; i < v1.size(); ++i)
- assert(v2[i] == ~v1[i]);
- }
+ 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];
+ std::bitset<N> v2 = v1;
+ v2.flip();
+ for (std::size_t i = 0; i < v1.size(); ++i)
+ assert(v2[i] == ~v1[i]);
+ }
}
TEST_CONSTEXPR_CXX23 bool test() {
test_flip_all<0>();
test_flip_all<1>();
+ test_flip_all<2>();
+ test_flip_all<5>();
test_flip_all<31>();
test_flip_all<32>();
test_flip_all<33>();
diff --git a/libcxx/test/std/utilities/template.bitset/bitset_test_cases.h b/libcxx/test/std/utilities/template.bitset/bitset_test_cases.h
index b561b01ef19a9..1ca19ec469e2c 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset_test_cases.h
+++ b/libcxx/test/std/utilities/template.bitset/bitset_test_cases.h
@@ -43,6 +43,28 @@ TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<2> > get_test_cases<2>() {
return cases;
}
+template <>
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<5> > get_test_cases<5>() {
+ std::vector<std::bitset<5> > cases;
+ cases.push_back(std::bitset<5>("00000"));
+ cases.push_back(std::bitset<5>("00001"));
+ cases.push_back(std::bitset<5>("10000"));
+ cases.push_back(std::bitset<5>("00010"));
+ cases.push_back(std::bitset<5>("01000"));
+ cases.push_back(std::bitset<5>("00011"));
+ cases.push_back(std::bitset<5>("11000"));
+ cases.push_back(std::bitset<5>("00100"));
+ cases.push_back(std::bitset<5>("11011"));
+ cases.push_back(std::bitset<5>("00101"));
+ cases.push_back(std::bitset<5>("10100"));
+ cases.push_back(std::bitset<5>("00110"));
+ cases.push_back(std::bitset<5>("01100"));
+ cases.push_back(std::bitset<5>("00111"));
+ cases.push_back(std::bitset<5>("11100"));
+ cases.push_back(std::bitset<5>("11111"));
+ return cases;
+}
+
template <>
TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<31> > get_test_cases<31>() {
std::vector<std::bitset<31> > cases;
More information about the libcxx-commits
mailing list