Skip to content

Commit a3d32ec

Browse files
committed
Fix no-op shrink_to_fit in vector<bool>
1 parent a6aa936 commit a3d32ec

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

libcxx/include/__vector/vector_bool.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -859,11 +859,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::reserve(size_type _
859859

860860
template <class _Allocator>
861861
_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT {
862-
if (__external_cap_to_internal(size()) > __cap_) {
862+
if (__external_cap_to_internal(size()) < __cap_) {
863863
#if _LIBCPP_HAS_EXCEPTIONS
864864
try {
865865
#endif // _LIBCPP_HAS_EXCEPTIONS
866-
vector(*this, allocator_type(__alloc_)).swap(*this);
866+
vector __v(*this, allocator_type(__alloc_));
867+
if (__v.__cap_ < __cap_)
868+
__v.swap(*this);
867869
#if _LIBCPP_HAS_EXCEPTIONS
868870
} catch (...) {
869871
}

libcxx/test/std/containers/sequences/vector.bool/shrink_to_fit.pass.cpp

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111

1212
// void shrink_to_fit();
1313

14+
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
15+
1416
#include <cassert>
17+
#include <climits>
1518
#include <vector>
1619

1720
#include "increasing_allocator.h"
@@ -20,21 +23,48 @@
2023

2124
TEST_CONSTEXPR_CXX20 bool tests() {
2225
{
23-
std::vector<bool> v(100);
26+
using C = std::vector<bool>;
27+
C v(100);
2428
v.push_back(1);
29+
v.clear();
2530
v.shrink_to_fit();
26-
assert(v.capacity() >= 101);
27-
assert(v.size() >= 101);
31+
assert(v.capacity() == 0);
32+
assert(v.size() == 0);
2833
}
29-
#if TEST_STD_VER >= 11
3034
{
31-
std::vector<bool, min_allocator<bool>> v(100);
35+
using C = std::vector<bool, min_allocator<bool> >;
36+
C v(100);
3237
v.push_back(1);
38+
C::size_type before_cap = v.capacity();
3339
v.shrink_to_fit();
3440
assert(v.capacity() >= 101);
35-
assert(v.size() >= 101);
41+
assert(v.capacity() <= before_cap);
42+
assert(v.size() == 101);
43+
}
44+
{
45+
using C = std::vector<bool>;
46+
unsigned bits_per_word = static_cast<unsigned>(sizeof(C::__storage_type) * CHAR_BIT);
47+
C v(bits_per_word);
48+
v.push_back(1);
49+
assert(v.capacity() == bits_per_word * 2);
50+
assert(v.size() == bits_per_word + 1);
51+
v.pop_back();
52+
v.shrink_to_fit();
53+
assert(v.capacity() == bits_per_word);
54+
assert(v.size() == bits_per_word);
55+
}
56+
{
57+
using C = std::vector<bool>;
58+
unsigned bits_per_word = static_cast<unsigned>(sizeof(C::__storage_type) * CHAR_BIT);
59+
C v;
60+
v.reserve(bits_per_word * 2);
61+
v.push_back(1);
62+
assert(v.capacity() == bits_per_word * 2);
63+
assert(v.size() == 1);
64+
v.shrink_to_fit();
65+
assert(v.capacity() == bits_per_word);
66+
assert(v.size() == 1);
3667
}
37-
#endif
3868

3969
return true;
4070
}

0 commit comments

Comments
 (0)