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(size_type res_arg);
12 
13 // This test relies on https://llvm.org/PR45368 being fixed, which isn't in
14 // older Apple dylibs
15 //
16 // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
17 
18 #include <string>
19 #include <stdexcept>
20 #include <cassert>
21 
22 #include "test_macros.h"
23 #include "min_allocator.h"
24 
25 template <class S>
26 void
27 test(typename S::size_type min_cap, typename S::size_type erased_index, typename S::size_type res_arg)
28 {
29     S s(min_cap, 'a');
30     s.erase(erased_index);
31     assert(s.size() == erased_index);
32     assert(s.capacity() >= min_cap); // Check that we really have at least this capacity.
33 
34 #if TEST_STD_VER > 17
35     typename S::size_type old_cap = s.capacity();
36 #endif
37     S s0 = s;
38     if (res_arg <= s.max_size())
39     {
40         s.reserve(res_arg);
41         LIBCPP_ASSERT(s.__invariants());
42         assert(s == s0);
43         assert(s.capacity() >= res_arg);
44         assert(s.capacity() >= s.size());
45 #if TEST_STD_VER > 17
46         assert(s.capacity() >= old_cap); // reserve never shrinks as of P0966 (C++20)
47 #endif
48     }
49 #ifndef TEST_HAS_NO_EXCEPTIONS
50     else
51     {
52         try
53         {
54             s.reserve(res_arg);
55             LIBCPP_ASSERT(s.__invariants());
56             assert(false);
57         }
58         catch (std::length_error&)
59         {
60             assert(res_arg > s.max_size());
61         }
62     }
63 #endif
64 }
65 
66 bool test() {
67   {
68     typedef std::string S;
69     {
70       test<S>(0, 0, 5);
71       test<S>(0, 0, 10);
72       test<S>(0, 0, 50);
73     }
74     {
75       test<S>(100, 50, 5);
76       test<S>(100, 50, 10);
77       test<S>(100, 50, 50);
78       test<S>(100, 50, 100);
79       test<S>(100, 50, 1000);
80       test<S>(100, 50, S::npos);
81     }
82   }
83 #if TEST_STD_VER >= 11
84   {
85     typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
86     {
87       test<S>(0, 0, 5);
88       test<S>(0, 0, 10);
89       test<S>(0, 0, 50);
90     }
91     {
92       test<S>(100, 50, 5);
93       test<S>(100, 50, 10);
94       test<S>(100, 50, 50);
95       test<S>(100, 50, 100);
96       test<S>(100, 50, 1000);
97       test<S>(100, 50, S::npos);
98     }
99   }
100 #endif
101 
102   return true;
103 }
104 
105 int main(int, char**)
106 {
107   test();
108 #if TEST_STD_VER > 17
109   // static_assert(test());
110 #endif
111 
112   return 0;
113 }
114