xref: /llvm-project/libcxx/test/std/strings/basic.string/string.capacity/max_size.pass.cpp (revision 04ce0baf015ced39e994b8839e30bd5cef6c995e)
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 // UNSUPPORTED: no-exceptions
10 
11 // After changing the alignment of the allocated pointer from 16 to 8, the exception thrown is no longer `bad_alloc`
12 // but instead length_error on systems using new headers but older dylibs.
13 //
14 // XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx{{10.13|10.15|11.0}}
15 
16 // <string>
17 
18 // size_type max_size() const; // constexpr since C++20
19 
20 // NOTE: asan and msan will fail for one of two reasons
21 // 1. If allocator_may_return_null=0 then they will fail because the allocation
22 //    returns null.
23 // 2. If allocator_may_return_null=1 then they will fail because the allocation
24 //    is too large to succeed.
25 // UNSUPPORTED: sanitizer-new-delete
26 
27 #include <string>
28 #include <cassert>
29 #include <new>
30 
31 #include "test_macros.h"
32 #include "min_allocator.h"
33 
34 template <class S>
35 TEST_CONSTEXPR_CXX20 void test_resize_max_size_minus_1(const S& s) {
36   S s2(s);
37   const std::size_t sz = s2.max_size() - 1;
38   try {
39     s2.resize(sz, 'x');
40   } catch (const std::bad_alloc&) {
41     return;
42   }
43   assert(s2.size() == sz);
44 }
45 
46 template <class S>
47 TEST_CONSTEXPR_CXX20 void test_resize_max_size(const S& s) {
48   S s2(s);
49   const std::size_t sz = s2.max_size();
50   try {
51     s2.resize(sz, 'x');
52   } catch (const std::bad_alloc&) {
53     return;
54   }
55   assert(s.size() == sz);
56 }
57 
58 template <class S>
59 TEST_CONSTEXPR_CXX20 void test_string() {
60   {
61     S s;
62     assert(s.max_size() >= s.size());
63     assert(s.max_size() > 0);
64     if (!TEST_IS_CONSTANT_EVALUATED) {
65       test_resize_max_size_minus_1(s);
66       test_resize_max_size(s);
67     }
68   }
69   {
70     S s("123");
71     assert(s.max_size() >= s.size());
72     assert(s.max_size() > 0);
73     if (!TEST_IS_CONSTANT_EVALUATED) {
74       test_resize_max_size_minus_1(s);
75       test_resize_max_size(s);
76     }
77   }
78   {
79     S s("12345678901234567890123456789012345678901234567890");
80     assert(s.max_size() >= s.size());
81     assert(s.max_size() > 0);
82     if (!TEST_IS_CONSTANT_EVALUATED) {
83       test_resize_max_size_minus_1(s);
84       test_resize_max_size(s);
85     }
86   }
87 }
88 
89 TEST_CONSTEXPR_CXX20 bool test() {
90   test_string<std::string>();
91 #if TEST_STD_VER >= 11
92   test_string<std::basic_string<char, std::char_traits<char>, min_allocator<char> > >();
93 #endif
94 
95   return true;
96 }
97 
98 int main(int, char**) {
99   test();
100 #if TEST_STD_VER >= 20
101   static_assert(test());
102 #endif
103 
104   return 0;
105 }
106