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