1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // <string>
10
11 // void reserve(); // Deprecated in C++20.
12 // void reserve(size_type);
13
14 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX26_REMOVED_STRING_RESERVE
15
16 // This test ensures that libc++ implements https://wg21.link/P0966R1 (reserve never shrinks)
17 // even before C++20. This is required in order to avoid ODR violations because basic_string::reserve(size)
18 // is compiled into the shared library. Hence, it needs to have the same definition in all Standard modes.
19 //
20 // However, note that reserve() does shrink, and it does so in all Standard modes.
21 //
22 // Reported as https://llvm.org/PR53170.
23
24 // reserve(n) used to shrink the string until https://llvm.org/D117332 was shipped in LLVM 14.
25 // XFAIL: using-built-library-before-llvm-14
26
27 #include <string>
28 #include <stdexcept>
29 #include <cassert>
30
31 #include "test_macros.h"
32 #include "min_allocator.h"
33
34 template <class S>
test()35 TEST_CONSTEXPR_CXX20 bool test() {
36 // Test that a call to reserve() does shrink the string.
37 if (!TEST_IS_CONSTANT_EVALUATED) {
38 S s(1000, 'a');
39 typename S::size_type old_cap = s.capacity();
40 s.resize(20);
41 assert(s.capacity() == old_cap);
42
43 s.reserve();
44 assert(s.capacity() < old_cap);
45 }
46
47 // Test that a call to reserve(smaller-than-capacity) never shrinks the string.
48 {
49 S s(1000, 'a');
50 typename S::size_type old_cap = s.capacity();
51 s.resize(20);
52 assert(s.capacity() == old_cap);
53
54 s.reserve(10);
55 assert(s.capacity() == old_cap);
56 }
57
58 // In particular, test that reserve(0) does NOT shrink the string.
59 {
60 S s(1000, 'a');
61 typename S::size_type old_cap = s.capacity();
62 s.resize(20);
63 assert(s.capacity() == old_cap);
64
65 s.reserve(0);
66 assert(s.capacity() == old_cap);
67 }
68
69 return true;
70 }
71
main(int,char **)72 int main(int, char**) {
73 test<std::string>();
74
75 #if TEST_STD_VER >= 11
76 test<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
77 #endif
78
79 #if TEST_STD_VER > 17
80 static_assert(test<std::string>());
81 #endif
82
83 return 0;
84 }
85