xref: /llvm-project/libcxx/test/libcxx/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 // <string>
10 
11 // This test ensures that the correct max_size() is returned depending on the platform.
12 
13 #include <algorithm>
14 #include <cassert>
15 #include <cstddef>
16 #include <string>
17 
18 #include "test_macros.h"
19 
20 // alignment of the string heap buffer is hardcoded to 8
21 static const std::size_t alignment = 8;
22 
23 template <class = int>
full_size()24 TEST_CONSTEXPR_CXX20 void full_size() {
25   std::string str;
26   assert(str.max_size() == std::numeric_limits<std::size_t>::max() - alignment);
27 
28 #ifndef TEST_HAS_NO_CHAR8_T
29   std::u8string u8str;
30   assert(u8str.max_size() == std::numeric_limits<std::size_t>::max() - alignment);
31 #endif
32 
33 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
34   std::wstring wstr;
35   assert(wstr.max_size() == std::numeric_limits<std::size_t>::max() / sizeof(wchar_t) - alignment);
36 #endif
37 
38   std::u16string u16str;
39   std::u32string u32str;
40   assert(u16str.max_size() == std::numeric_limits<std::size_t>::max() / 2 - alignment);
41   assert(u32str.max_size() == std::numeric_limits<std::size_t>::max() / 4 - alignment);
42 }
43 
44 template <class = int>
half_size()45 TEST_CONSTEXPR_CXX20 void half_size() {
46   std::string str;
47   assert(str.max_size() == std::numeric_limits<std::size_t>::max() / 2 - alignment);
48 
49 #ifndef TEST_HAS_NO_CHAR8_T
50   std::u8string u8str;
51   assert(u8str.max_size() == std::numeric_limits<std::size_t>::max() / 2 - alignment);
52 #endif
53 
54 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
55   std::wstring wstr;
56   assert(wstr.max_size() ==
57          std::numeric_limits<std::size_t>::max() / std::max<size_t>(2ul, sizeof(wchar_t)) - alignment);
58 #endif
59 
60   std::u16string u16str;
61   std::u32string u32str;
62   assert(u16str.max_size() == std::numeric_limits<std::size_t>::max() / 2 - alignment);
63   assert(u32str.max_size() == std::numeric_limits<std::size_t>::max() / 4 - alignment);
64 }
65 
test()66 TEST_CONSTEXPR_CXX20 bool test() {
67 #if _LIBCPP_ABI_VERSION == 1
68 
69 #  if defined(__x86_64__) || defined(__i386__)
70   full_size();
71 #  elif defined(__APPLE__) && defined(__aarch64__)
72   half_size();
73 #  elif defined(__arm__) || defined(__aarch64__)
74 #    ifdef __BIG_ENDIAN__
75   half_size();
76 #    else
77   full_size();
78 #    endif
79 #  elif defined(__powerpc__) || defined(__powerpc64__)
80 #    ifdef __BIG_ENDIAN__
81   half_size();
82 #    else
83   full_size();
84 #    endif
85 #  elif defined(__sparc64__)
86   half_size();
87 #  elif defined(__riscv)
88   full_size();
89 #  elif defined(_WIN32)
90   full_size();
91 #  else
92 #    error "Your target system seems to be unsupported."
93 #  endif
94 
95 #else
96 
97 #  if defined(__arm__) || defined(__aarch64__)
98 #    ifdef __BIG_ENDIAN__
99   full_size();
100 #    else
101   half_size();
102 #    endif
103 #  else
104   half_size();
105 #  endif
106 
107 #endif
108 
109   return true;
110 }
111 
main(int,char **)112 int main(int, char**) {
113   test();
114 #if TEST_STD_VER > 17
115   static_assert(test());
116 #endif
117 
118   return 0;
119 }
120