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
38namespace std {
39namespace __lldb {
40
41#ifdef NON_STANDARD_PADDING
42#if defined(ALTERNATE_LAYOUT) && defined(SUBCLASS_PADDING)
43template <class _CharT, size_t = sizeof(_CharT)> struct __padding {
44 unsigned char __xx[sizeof(_CharT) - 1];
45};
46
47template <class _CharT> struct __padding<_CharT, 1> {};
48#endif
49#else // !NON_STANDARD_PADDING
50template <size_t _PaddingSize> struct __padding {
51 char __padding_[_PaddingSize];
52};
53
54template <> struct __padding<0> {};
55#endif
56
57template <class _CharT, class _Traits, class _Allocator> class basic_string {
58public:
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
231public:
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
256using string = basic_string<char, std::char_traits<char>, std::allocator<char>>;
257
258} // namespace __lldb
259} // namespace std
260
261int 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

source code of lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx-simulators/string/main.cpp