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