xref: /llvm-project/libcxx/test/std/strings/basic.string/string.capacity/reserve.pass.cpp (revision 25838c6dacca8203b4478ac2c16e563b51c3708b)
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 // Split into two calls for C++20
12 // void reserve();
13 // void reserve(size_type res_arg);
14 
15 // When back-deploying to macosx10.7, the RTTI for exception classes
16 // incorrectly provided by libc++.dylib is mixed with the one in
17 // libc++abi.dylib and exceptions are not caught properly.
18 // XFAIL: with_system_cxx_lib=macosx10.7
19 
20 #include <string>
21 #include <stdexcept>
22 #include <cassert>
23 
24 #include "test_macros.h"
25 #include "min_allocator.h"
26 
27 template <class S>
28 void
29 test(S s)
30 {
31     typename S::size_type old_cap = s.capacity();
32     S s0 = s;
33     s.reserve();
34     LIBCPP_ASSERT(s.__invariants());
35     assert(s == s0);
36     assert(s.capacity() <= old_cap);
37     assert(s.capacity() >= s.size());
38 }
39 
40 template <class S>
41 void
42 test(S s, typename S::size_type res_arg)
43 {
44     typename S::size_type old_cap = s.capacity();
45     ((void)old_cap); // Prevent unused warning
46     S s0 = s;
47     if (res_arg <= s.max_size())
48     {
49         s.reserve(res_arg);
50         assert(s == s0);
51         assert(s.capacity() >= res_arg);
52         assert(s.capacity() >= s.size());
53 #if TEST_STD_VER > 17
54         assert(s.capacity() >= old_cap); // resize never shrinks as of P0966
55 #endif
56     }
57 #ifndef TEST_HAS_NO_EXCEPTIONS
58     else
59     {
60         try
61         {
62             s.reserve(res_arg);
63             assert(false);
64         }
65         catch (std::length_error&)
66         {
67             assert(res_arg > s.max_size());
68         }
69     }
70 #endif
71 }
72 
73 int main(int, char**)
74 {
75     {
76     typedef std::string S;
77     {
78     S s;
79     test(s);
80 
81     s.assign(10, 'a');
82     s.erase(5);
83     test(s);
84 
85     s.assign(100, 'a');
86     s.erase(50);
87     test(s);
88     }
89     {
90     S s;
91     test(s, 5);
92     test(s, 10);
93     test(s, 50);
94     }
95     {
96     S s(100, 'a');
97     s.erase(50);
98     test(s, 5);
99     test(s, 10);
100     test(s, 50);
101     test(s, 100);
102     test(s, 1000);
103     test(s, S::npos);
104     }
105     }
106 #if TEST_STD_VER >= 11
107     {
108     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
109     {
110     S s;
111     test(s);
112 
113     s.assign(10, 'a');
114     s.erase(5);
115     test(s);
116 
117     s.assign(100, 'a');
118     s.erase(50);
119     test(s);
120     }
121     {
122     S s;
123     test(s, 5);
124     test(s, 10);
125     test(s, 50);
126     }
127     {
128     S s(100, 'a');
129     s.erase(50);
130     test(s, 5);
131     test(s, 10);
132     test(s, 50);
133     test(s, 100);
134     test(s, 1000);
135     test(s, S::npos);
136     }
137     }
138 #endif
139 
140   return 0;
141 }
142