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