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