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