xref: /llvm-project/libcxx/test/libcxx/strings/basic.string/sizeof.compile.pass.cpp (revision 09e3a360581dc36d0820d3fb6da9bd7cfed87b5d)
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 // Ensure that we never change the size or alignment of `basic_string`
10 
11 #include <cstdint>
12 #include <iterator>
13 #include <string>
14 
15 #include "test_macros.h"
16 #include "min_allocator.h"
17 #include "test_allocator.h"
18 
19 template <class T>
20 class small_pointer {
21 public:
22   using value_type        = T;
23   using difference_type   = std::int16_t;
24   using pointer           = small_pointer;
25   using reference         = T&;
26   using iterator_category = std::random_access_iterator_tag;
27 
28 private:
29   std::uint16_t offset;
30 };
31 
32 template <class T>
33 class small_iter_allocator {
34 public:
35   using value_type      = T;
36   using pointer         = small_pointer<T>;
37   using size_type       = std::int16_t;
38   using difference_type = std::int16_t;
39 
40   small_iter_allocator() TEST_NOEXCEPT {}
41 
42   template <class U>
43   small_iter_allocator(small_iter_allocator<U>) TEST_NOEXCEPT {}
44 
45   T* allocate(std::size_t n);
46   void deallocate(T* p, std::size_t);
47 
48   friend bool operator==(small_iter_allocator, small_iter_allocator) { return true; }
49   friend bool operator!=(small_iter_allocator, small_iter_allocator) { return false; }
50 };
51 
52 template <class CharT>
53 using min_string = std::basic_string<CharT, std::char_traits<CharT>, min_allocator<CharT> >;
54 
55 template <class CharT>
56 using test_string = std::basic_string<CharT, std::char_traits<CharT>, test_allocator<CharT> >;
57 
58 template <class CharT>
59 using small_string = std::basic_string<CharT, std::char_traits<CharT>, small_iter_allocator<CharT> >;
60 
61 #if __SIZE_WIDTH__ == 64
62 
63 static_assert(sizeof(std::string) == 24, "");
64 static_assert(sizeof(min_string<char>) == 24, "");
65 static_assert(sizeof(test_string<char>) == 32, "");
66 static_assert(sizeof(small_string<char>) == 6, "");
67 
68 #  ifndef TEST_HAS_NO_WIDE_CHARACTERS
69 #    if __WCHAR_WIDTH__ == 32
70 static_assert(sizeof(std::wstring) == 24, "");
71 static_assert(sizeof(min_string<wchar_t>) == 24, "");
72 static_assert(sizeof(test_string<wchar_t>) == 32, "");
73 static_assert(sizeof(small_string<wchar_t>) == 12, "");
74 #    elif __WCHAR_WIDTH__ == 16
75 static_assert(sizeof(std::wstring) == 24, "");
76 static_assert(sizeof(min_string<wchar_t>) == 24, "");
77 static_assert(sizeof(test_string<wchar_t>) == 32, "");
78 static_assert(sizeof(small_string<wchar_t>) == 6, "");
79 #    else
80 #      error "Unexpected wchar_t width"
81 #    endif
82 #  endif
83 
84 #  ifndef TEST_HAS_NO_CHAR8_T
85 static_assert(sizeof(std::u8string) == 24, "");
86 static_assert(sizeof(min_string<char8_t>) == 24, "");
87 static_assert(sizeof(test_string<char8_t>) == 32, "");
88 static_assert(sizeof(small_string<char8_t>) == 6, "");
89 #  endif
90 
91 #  ifndef TEST_HAS_NO_UNICODE_CHARS
92 static_assert(sizeof(std::u16string) == 24, "");
93 static_assert(sizeof(std::u32string) == 24, "");
94 static_assert(sizeof(min_string<char16_t>) == 24, "");
95 static_assert(sizeof(min_string<char32_t>) == 24, "");
96 static_assert(sizeof(test_string<char16_t>) == 32, "");
97 static_assert(sizeof(test_string<char32_t>) == 32, "");
98 static_assert(sizeof(small_string<char16_t>) == 6, "");
99 static_assert(sizeof(small_string<char32_t>) == 12, "");
100 #  endif
101 
102 #elif __SIZE_WIDTH__ == 32
103 
104 static_assert(sizeof(std::string) == 12, "");
105 static_assert(sizeof(min_string<char>) == 12, "");
106 static_assert(sizeof(test_string<char>) == 24, "");
107 static_assert(sizeof(small_string<char>) == 6, "");
108 
109 #  ifndef TEST_HAS_NO_WIDE_CHARACTERS
110 #    if __WCHAR_WIDTH__ == 32
111 static_assert(sizeof(std::wstring) == 12, "");
112 static_assert(sizeof(min_string<wchar_t>) == 12, "");
113 static_assert(sizeof(test_string<wchar_t>) == 24, "");
114 static_assert(sizeof(small_string<wchar_t>) == 12, "");
115 #    elif __WCHAR_WIDTH__ == 16
116 static_assert(sizeof(std::wstring) == 12, "");
117 static_assert(sizeof(min_string<wchar_t>) == 12, "");
118 static_assert(sizeof(test_string<wchar_t>) == 24, "");
119 static_assert(sizeof(small_string<wchar_t>) == 6, "");
120 #    else
121 #      error "Unexpected wchar_t width"
122 #    endif
123 #  endif
124 
125 #  ifndef TEST_HAS_NO_CHAR8_T
126 static_assert(sizeof(std::u8string) == 12, "");
127 static_assert(sizeof(min_string<char8_t>) == 12, "");
128 static_assert(sizeof(test_string<char8_t>) == 24, "");
129 static_assert(sizeof(small_string<char>) == 6, "");
130 #  endif
131 
132 #  ifndef TEST_HAS_NO_UNICODE_CHARS
133 static_assert(sizeof(std::u16string) == 12, "");
134 static_assert(sizeof(std::u32string) == 12, "");
135 static_assert(sizeof(min_string<char16_t>) == 12, "");
136 static_assert(sizeof(min_string<char32_t>) == 12, "");
137 static_assert(sizeof(test_string<char16_t>) == 24, "");
138 static_assert(sizeof(test_string<char32_t>) == 24, "");
139 static_assert(sizeof(small_string<char16_t>) == 6, "");
140 static_assert(sizeof(small_string<char32_t>) == 12, "");
141 #  endif
142 
143 #else
144 #  error "std::size_t has an unexpected size"
145 #endif
146