1 | #include <libcxx-simulators-common/compressed_pair.h> |
2 | |
3 | #include <climits> |
4 | #include <memory> |
5 | #include <type_traits> |
6 | |
7 | #if REVISION == 0 |
8 | // Pre-c3d0205ee771 layout. |
9 | #define SUBCLASS_PADDING |
10 | #endif |
11 | #if REVISION <= 1 |
12 | // Pre-D123580 layout. |
13 | #define BITMASKS |
14 | #endif |
15 | #if REVISION <= 2 |
16 | // Pre-D125496 layout. |
17 | #define SHORT_UNION |
18 | #endif |
19 | #if REVISION == 3 |
20 | // Pre-D128285 layout. |
21 | #define PACKED_ANON_STRUCT |
22 | #endif |
23 | #if REVISION <= 4 |
24 | // Pre-2a1ef74 layout. |
25 | #define NON_STANDARD_PADDING |
26 | #endif |
27 | // REVISION == 5: current layout |
28 | |
29 | #ifdef PACKED_ANON_STRUCT |
30 | #define BEGIN_PACKED_ANON_STRUCT struct __attribute__((packed)) { |
31 | #define END_PACKED_ANON_STRUCT }; |
32 | #else |
33 | #define BEGIN_PACKED_ANON_STRUCT |
34 | #define END_PACKED_ANON_STRUCT |
35 | #endif |
36 | |
37 | |
38 | namespace std { |
39 | namespace __lldb { |
40 | |
41 | #ifdef NON_STANDARD_PADDING |
42 | #if defined(ALTERNATE_LAYOUT) && defined(SUBCLASS_PADDING) |
43 | template <class _CharT, size_t = sizeof(_CharT)> struct __padding { |
44 | unsigned char __xx[sizeof(_CharT) - 1]; |
45 | }; |
46 | |
47 | template <class _CharT> struct __padding<_CharT, 1> {}; |
48 | #endif |
49 | #else // !NON_STANDARD_PADDING |
50 | template <size_t _PaddingSize> struct __padding { |
51 | char __padding_[_PaddingSize]; |
52 | }; |
53 | |
54 | template <> struct __padding<0> {}; |
55 | #endif |
56 | |
57 | template <class _CharT, class _Traits, class _Allocator> class basic_string { |
58 | public: |
59 | typedef _CharT value_type; |
60 | typedef _Allocator allocator_type; |
61 | typedef allocator_traits<allocator_type> __alloc_traits; |
62 | typedef typename __alloc_traits::size_type size_type; |
63 | typedef typename __alloc_traits::pointer pointer; |
64 | |
65 | #ifdef ALTERNATE_LAYOUT |
66 | |
67 | struct __long { |
68 | pointer __data_; |
69 | size_type __size_; |
70 | #ifdef BITMASKS |
71 | size_type __cap_; |
72 | #else |
73 | size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; |
74 | size_type __is_long_ : 1; |
75 | #endif |
76 | }; |
77 | |
78 | enum { |
79 | __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 |
80 | ? (sizeof(__long) - 1) / sizeof(value_type) |
81 | : 2 |
82 | }; |
83 | |
84 | struct __short { |
85 | value_type __data_[__min_cap]; |
86 | #ifdef SUBCLASS_PADDING |
87 | struct : __padding<value_type> { |
88 | unsigned char __size_; |
89 | }; |
90 | #else // !SUBCLASS_PADDING |
91 | |
92 | #ifdef NON_STANDARD_PADDING |
93 | unsigned char __padding[sizeof(value_type) - 1]; |
94 | #else |
95 | _LLDB_NO_UNIQUE_ADDRESS __padding<sizeof(value_type) - 1> __padding_; |
96 | #endif |
97 | |
98 | #ifdef BITMASKS |
99 | unsigned char __size_; |
100 | #else // !BITMASKS |
101 | unsigned char __size_ : 7; |
102 | unsigned char __is_long_ : 1; |
103 | #endif // BITMASKS |
104 | #endif // SUBCLASS_PADDING |
105 | }; |
106 | |
107 | #ifdef BITMASKS |
108 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
109 | static const size_type __short_shift = 1; |
110 | static const size_type __long_mask = 0x1ul; |
111 | #else |
112 | static const size_type __short_shift = 0; |
113 | static const size_type __long_mask = ~(size_type(~0) >> 1); |
114 | #endif |
115 | #else // !BITMASKS |
116 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
117 | static const size_type __endian_factor = 2; |
118 | #else |
119 | static const size_type __endian_factor = 1; |
120 | #endif |
121 | #endif // BITMASKS |
122 | |
123 | #else // !ALTERNATE_LAYOUT |
124 | |
125 | struct __long { |
126 | #ifdef BITMASKS |
127 | size_type __cap_; |
128 | #else |
129 | BEGIN_PACKED_ANON_STRUCT |
130 | size_type __is_long_ : 1; |
131 | size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; |
132 | END_PACKED_ANON_STRUCT |
133 | #endif |
134 | size_type __size_; |
135 | pointer __data_; |
136 | }; |
137 | |
138 | enum { |
139 | __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 |
140 | ? (sizeof(__long) - 1) / sizeof(value_type) |
141 | : 2 |
142 | }; |
143 | |
144 | struct __short { |
145 | #ifdef SHORT_UNION |
146 | union { |
147 | #ifdef BITMASKS |
148 | unsigned char __size_; |
149 | #else // !BITMASKS |
150 | struct { |
151 | unsigned char __is_long_ : 1; |
152 | unsigned char __size_ : 7; |
153 | }; |
154 | #endif // BITMASKS |
155 | value_type __lx; |
156 | }; |
157 | #else // !SHORT_UNION |
158 | BEGIN_PACKED_ANON_STRUCT |
159 | unsigned char __is_long_ : 1; |
160 | unsigned char __size_ : 7; |
161 | END_PACKED_ANON_STRUCT |
162 | #ifdef NON_STANDARD_PADDING |
163 | unsigned char __padding[sizeof(value_type) - 1]; |
164 | #else // !NON_STANDARD_PADDING |
165 | _LLDB_NO_UNIQUE_ADDRESS __padding<sizeof(value_type) - 1> __padding_; |
166 | #endif // NON_STANDARD_PADDING |
167 | |
168 | #endif // SHORT_UNION |
169 | value_type __data_[__min_cap]; |
170 | }; |
171 | |
172 | #ifdef BITMASKS |
173 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
174 | static const size_type __short_shift = 0; |
175 | static const size_type __long_mask = ~(size_type(~0) >> 1); |
176 | #else |
177 | static const size_type __short_shift = 1; |
178 | static const size_type __long_mask = 0x1ul; |
179 | #endif |
180 | #else // !BITMASKS |
181 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
182 | static const size_type __endian_factor = 1; |
183 | #else |
184 | static const size_type __endian_factor = 2; |
185 | #endif |
186 | #endif |
187 | |
188 | #endif // ALTERNATE_LAYOUT |
189 | |
190 | union __ulx { |
191 | __long __lx; |
192 | __short __lxx; |
193 | }; |
194 | |
195 | enum { __n_words = sizeof(__ulx) / sizeof(size_type) }; |
196 | |
197 | struct __raw { |
198 | size_type __words[__n_words]; |
199 | }; |
200 | |
201 | struct __rep { |
202 | union { |
203 | __long __l; |
204 | __short __s; |
205 | __raw __r; |
206 | }; |
207 | }; |
208 | |
209 | __long &getLongRep() { |
210 | #if COMPRESSED_PAIR_REV == 0 |
211 | return __r_.first().__l; |
212 | #elif COMPRESSED_PAIR_REV <= 2 |
213 | return __rep_.__l; |
214 | #endif |
215 | } |
216 | |
217 | __short &getShortRep() { |
218 | #if COMPRESSED_PAIR_REV == 0 |
219 | return __r_.first().__s; |
220 | #elif COMPRESSED_PAIR_REV <= 2 |
221 | return __rep_.__s; |
222 | #endif |
223 | } |
224 | |
225 | #if COMPRESSED_PAIR_REV == 0 |
226 | std::__lldb::__compressed_pair<__rep, allocator_type> __r_; |
227 | #elif COMPRESSED_PAIR_REV <= 2 |
228 | _LLDB_COMPRESSED_PAIR(__rep, __rep_, allocator_type, __alloc_); |
229 | #endif |
230 | |
231 | public: |
232 | template <size_t __N> |
233 | basic_string(unsigned char __size, const value_type (&__data)[__N]) { |
234 | static_assert(__N < __min_cap, "" ); |
235 | #ifdef BITMASKS |
236 | getShortRep().__size_ = __size << __short_shift; |
237 | #else |
238 | getShortRep().__size_ = __size; |
239 | getShortRep().__is_long_ = false; |
240 | #endif |
241 | for (size_t __i = 0; __i < __N; ++__i) |
242 | getShortRep().__data_[__i] = __data[__i]; |
243 | } |
244 | basic_string(size_t __cap, size_type __size, pointer __data) { |
245 | #ifdef BITMASKS |
246 | getLongRep().__cap_ = __cap | __long_mask; |
247 | #else |
248 | getLongRep().__cap_ = __cap / __endian_factor; |
249 | getLongRep().__is_long_ = true; |
250 | #endif |
251 | getLongRep().__size_ = __size; |
252 | getLongRep().__data_ = __data; |
253 | } |
254 | }; |
255 | |
256 | using string = basic_string<char, std::char_traits<char>, std::allocator<char>>; |
257 | |
258 | } // namespace __lldb |
259 | } // namespace std |
260 | |
261 | int main() { |
262 | char longdata[] = "I am a very long string" ; |
263 | std::__lldb::string longstring(sizeof(longdata), sizeof(longdata) - 1, |
264 | longdata); |
265 | std::__lldb::string shortstring(5, "short" ); |
266 | return 0; // Break here |
267 | } |
268 | |