xref: /llvm-project/libcxx/test/std/strings/basic.string/string.capacity/shrink_to_fit.pass.cpp (revision a821937b6d29f874d2561c6ef073faeed302b1a9)
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 shrink_to_fit(); // constexpr since C++20
12 
13 #include <cassert>
14 #include <string>
15 
16 #include "asan_testing.h"
17 #include "increasing_allocator.h"
18 #include "min_allocator.h"
19 #include "test_macros.h"
20 
21 template <class S>
22 TEST_CONSTEXPR_CXX20 void test(S s) {
23   typename S::size_type old_cap = s.capacity();
24   S s0                          = s;
25   s.shrink_to_fit();
26   LIBCPP_ASSERT(s.__invariants());
27   assert(s == s0);
28   assert(s.capacity() <= old_cap);
29   assert(s.capacity() >= s.size());
30   LIBCPP_ASSERT(is_string_asan_correct(s));
31 }
32 
33 template <class S>
34 TEST_CONSTEXPR_CXX20 void test_string() {
35   S s;
36   test(s);
37 
38   s.assign(10, 'a');
39   s.erase(5);
40   test(s);
41 
42   s.assign(50, 'a');
43   s.erase(5);
44   test(s);
45 
46   s.assign(100, 'a');
47   s.erase(50);
48   test(s);
49 
50   s.assign(100, 'a');
51   for (int i = 0; i <= 9; ++i) {
52     s.erase(90 - 10 * i);
53     test(s);
54   }
55 }
56 
57 TEST_CONSTEXPR_CXX20 bool test() {
58   test_string<std::string>();
59 #if TEST_STD_VER >= 11
60   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char>>>();
61   test_string<std::basic_string<char, std::char_traits<char>, safe_allocator<char>>>();
62 #endif
63 
64   return true;
65 }
66 
67 #if TEST_STD_VER >= 23
68 // https://github.com/llvm/llvm-project/issues/95161
69 void test_increasing_allocator() {
70   std::basic_string<char, std::char_traits<char>, increasing_allocator<char>> s{
71       "String does not fit in the internal buffer"};
72   std::size_t capacity = s.capacity();
73   std::size_t size     = s.size();
74   s.shrink_to_fit();
75   assert(s.capacity() <= capacity);
76   assert(s.size() == size);
77   LIBCPP_ASSERT(is_string_asan_correct(s));
78 }
79 #endif // TEST_STD_VER >= 23
80 
81 int main(int, char**) {
82   test();
83 #if TEST_STD_VER >= 23
84   test_increasing_allocator();
85 #endif
86 #if TEST_STD_VER > 17
87   static_assert(test());
88 #endif
89 
90   return 0;
91 }
92