[libcxx-commits] [libcxx] fafdf97 - [libc++] Simplify vector<bool>::flip() and add new tests (#119607)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Dec 19 08:48:55 PST 2024
Author: Peng Liu
Date: 2024-12-19T11:48:51-05:00
New Revision: fafdf97047b1d9622ffbb59919d2422e062882f2
URL: https://github.com/llvm/llvm-project/commit/fafdf97047b1d9622ffbb59919d2422e062882f2
DIFF: https://github.com/llvm/llvm-project/commit/fafdf97047b1d9622ffbb59919d2422e062882f2.diff
LOG: [libc++] Simplify vector<bool>::flip() and add new tests (#119607)
This PR simplifies the internal bitwise logic of the `flip()` function
for `vector<bool>`, and creates new tests to validate the changes.
Added:
libcxx/test/std/containers/sequences/vector.bool/flip.pass.cpp
Modified:
libcxx/include/__vector/vector_bool.h
Removed:
################################################################################
diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index 36eb7f350ac406..525fc35b26cc9e 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -1049,18 +1049,11 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::resize(size_type __
template <class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::flip() _NOEXCEPT {
- // do middle whole words
- size_type __n = __size_;
+ // Flip each storage word entirely, including the last potentially partial word.
+ // The unused bits in the last word are safe to flip as they won't be accessed.
__storage_pointer __p = __begin_;
- for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
+ for (size_type __n = __external_cap_to_internal(size()); __n != 0; ++__p, --__n)
*__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;
- }
}
template <class _Allocator>
diff --git a/libcxx/test/std/containers/sequences/vector.bool/flip.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/flip.pass.cpp
new file mode 100644
index 00000000000000..f8f575cdc0e219
--- /dev/null
+++ b/libcxx/test/std/containers/sequences/vector.bool/flip.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// void flip();
+
+#include <cassert>
+#include <memory>
+#include <vector>
+
+#include "min_allocator.h"
+#include "test_allocator.h"
+#include "test_macros.h"
+
+template <typename Allocator>
+TEST_CONSTEXPR_CXX20 void test_vector_flip(std::size_t n, Allocator a) {
+ std::vector<bool, Allocator> v(n, false, a);
+ for (std::size_t i = 0; i < n; ++i)
+ v[i] = i & 1;
+ std::vector<bool, Allocator> original = v;
+ v.flip();
+ for (size_t i = 0; i < n; ++i)
+ assert(v[i] == !original[i]);
+ v.flip();
+ assert(v == original);
+}
+
+TEST_CONSTEXPR_CXX20 bool tests() {
+ // Test small vectors with
diff erent allocators
+ test_vector_flip(3, std::allocator<bool>());
+ test_vector_flip(3, min_allocator<bool>());
+ test_vector_flip(3, test_allocator<bool>(5));
+
+ // Test large vectors with
diff erent allocators
+ test_vector_flip(1000, std::allocator<bool>());
+ test_vector_flip(1000, min_allocator<bool>());
+ test_vector_flip(1000, test_allocator<bool>(5));
+
+ return true;
+}
+
+int main(int, char**) {
+ tests();
+#if TEST_STD_VER >= 20
+ static_assert(tests());
+#endif
+ return 0;
+}
More information about the libcxx-commits
mailing list