diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h index 2b721e00058bc..b35f3f1fdf322 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::reserve(size_type _ template _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector::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 3bc639d0479f9..30efe047054ab 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 +#include #include #include "increasing_allocator.h" @@ -20,19 +23,56 @@ TEST_CONSTEXPR_CXX20 bool tests() { { - std::vector v(100); + using C = std::vector; + C v(100); v.push_back(1); + C::size_type before_cap = v.capacity(); + v.clear(); v.shrink_to_fit(); - assert(v.capacity() >= 101); - assert(v.size() >= 101); + assert(v.capacity() <= before_cap); + LIBCPP_ASSERT(v.capacity() == 0); // libc++ honors the shrink_to_fit request as a QOI matter + assert(v.size() == 0); } -#if TEST_STD_VER >= 11 { - std::vector> v(100); + using C = std::vector >; + 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); + v.erase(v.begin() + 1, v.end()); + v.shrink_to_fit(); + assert(v.capacity() <= before_cap); + LIBCPP_ASSERT(v.capacity() == C(1).capacity()); // libc++ honors the shrink_to_fit request as a QOI matter. + assert(v.size() == 1); + } + +#if defined(_LIBCPP_VERSION) + { + using C = std::vector; + unsigned bits_per_word = static_cast(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; + unsigned bits_per_word = static_cast(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