[libcxx-commits] [libcxx] [libc++] Fix no-op shrink_to_fit for vector<bool> (PR #120495)
Peng Liu via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 9 15:00:23 PST 2025
https://github.com/winner245 updated https://github.com/llvm/llvm-project/pull/120495
>From f2e48f43ed6b2eb933483f385d951f9157553b5e Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Wed, 18 Dec 2024 18:23:11 -0500
Subject: [PATCH] Fix no-op shrink_to_fit in vector<bool>
---
libcxx/include/__vector/vector_bool.h | 6 ++-
.../vector.bool/shrink_to_fit.pass.cpp | 44 ++++++++++++++++---
2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h
index 2b721e00058bc6..b35f3f1fdf322d 100644
--- a/libcxx/include/__vector/vector_bool.h
+++ b/libcxx/include/__vector/vector_bool.h
@@ -859,11 +859,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::reserve(size_type _
template <class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT {
- if (__external_cap_to_internal(size()) > __cap_) {
+ if (__external_cap_to_internal(size()) < __cap_) {
#if _LIBCPP_HAS_EXCEPTIONS
try {
#endif // _LIBCPP_HAS_EXCEPTIONS
- vector(*this, allocator_type(__alloc_)).swap(*this);
+ vector __v(*this, allocator_type(__alloc_));
+ if (__v.__cap_ < __cap_)
+ __v.swap(*this);
#if _LIBCPP_HAS_EXCEPTIONS
} catch (...) {
}
diff --git a/libcxx/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp
index 3bc639d0479f96..a9a269c1653973 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp
@@ -11,7 +11,10 @@
// void shrink_to_fit();
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
#include <cassert>
+#include <climits>
#include <vector>
#include "increasing_allocator.h"
@@ -20,21 +23,48 @@
TEST_CONSTEXPR_CXX20 bool tests() {
{
- std::vector<bool> v(100);
+ using C = std::vector<bool>;
+ C v(100);
v.push_back(1);
+ v.clear();
v.shrink_to_fit();
- assert(v.capacity() >= 101);
- assert(v.size() >= 101);
+ assert(v.capacity() == 0);
+ assert(v.size() == 0);
}
-#if TEST_STD_VER >= 11
{
- std::vector<bool, min_allocator<bool>> v(100);
+ using C = std::vector<bool, min_allocator<bool> >;
+ C v(100);
v.push_back(1);
+ C::size_type before_cap = v.capacity();
v.shrink_to_fit();
assert(v.capacity() >= 101);
- assert(v.size() >= 101);
+ assert(v.capacity() <= before_cap);
+ assert(v.size() == 101);
+ }
+ {
+ using C = std::vector<bool>;
+ unsigned bits_per_word = static_cast<unsigned>(sizeof(C::__storage_type) * CHAR_BIT);
+ C v(bits_per_word);
+ v.push_back(1);
+ assert(v.capacity() == bits_per_word * 2);
+ assert(v.size() == bits_per_word + 1);
+ v.pop_back();
+ v.shrink_to_fit();
+ assert(v.capacity() == bits_per_word);
+ assert(v.size() == bits_per_word);
+ }
+ {
+ using C = std::vector<bool>;
+ unsigned bits_per_word = static_cast<unsigned>(sizeof(C::__storage_type) * CHAR_BIT);
+ C v;
+ v.reserve(bits_per_word * 2);
+ v.push_back(1);
+ assert(v.capacity() == bits_per_word * 2);
+ assert(v.size() == 1);
+ v.shrink_to_fit();
+ assert(v.capacity() == bits_per_word);
+ assert(v.size() == 1);
}
-#endif
return true;
}
More information about the libcxx-commits
mailing list