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