Skip to content

Commit aaa56f9

Browse files
mordanteyuxuanchen1997
authored andcommitted
[libc++][vector<bool>] Tests shrink_to_fit requirement. (#98009)
Summary: `vector<bool>`'s shrink_to_fit implementation is using the "swap-to-free-container-resources-trick" which only shrinks when the input vector is empty. Since the request to shrink_to_fit is non-binding, this is a valid implementation. It is not a high-quality implementation. Since `vector<bool>` is not a very popular container the implementation has not been changed and only a test to validate the non-growing property has been added. This was discovered while investigating #95161. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251031
1 parent 3002596 commit aaa56f9

File tree

1 file changed

+44
-1
lines changed

1 file changed

+44
-1
lines changed

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

+44-1
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,54 @@ TEST_CONSTEXPR_CXX20 bool tests()
3939
return true;
4040
}
4141

42+
#if TEST_STD_VER >= 23
43+
template <typename T>
44+
struct increasing_allocator {
45+
using value_type = T;
46+
std::size_t min_elements = 1000;
47+
increasing_allocator() = default;
48+
49+
template <typename U>
50+
constexpr increasing_allocator(const increasing_allocator<U>& other) noexcept : min_elements(other.min_elements) {}
51+
52+
constexpr std::allocation_result<T*> allocate_at_least(std::size_t n) {
53+
if (n < min_elements)
54+
n = min_elements;
55+
min_elements += 1000;
56+
return std::allocator<T>{}.allocate_at_least(n);
57+
}
58+
constexpr T* allocate(std::size_t n) { return allocate_at_least(n).ptr; }
59+
constexpr void deallocate(T* p, std::size_t n) noexcept { std::allocator<T>{}.deallocate(p, n); }
60+
};
61+
62+
template <typename T, typename U>
63+
bool operator==(increasing_allocator<T>, increasing_allocator<U>) {
64+
return true;
65+
}
66+
67+
// https://github.com/llvm/llvm-project/issues/95161
68+
constexpr bool test_increasing_allocator() {
69+
std::vector<bool, increasing_allocator<bool>> v;
70+
v.push_back(1);
71+
std::size_t capacity = v.capacity();
72+
v.shrink_to_fit();
73+
assert(v.capacity() <= capacity);
74+
assert(v.size() == 1);
75+
76+
return true;
77+
}
78+
#endif // TEST_STD_VER >= 23
79+
4280
int main(int, char**)
4381
{
44-
tests();
82+
tests();
4583
#if TEST_STD_VER > 17
4684
static_assert(tests());
4785
#endif
86+
#if TEST_STD_VER >= 23
87+
test_increasing_allocator();
88+
static_assert(test_increasing_allocator());
89+
#endif // TEST_STD_VER >= 23
90+
4891
return 0;
4992
}

0 commit comments

Comments
 (0)