1 #ifndef STD_LLDB_COMPRESSED_PAIR_H 2 #define STD_LLDB_COMPRESSED_PAIR_H 3 4 #include <type_traits> 5 #include <utility> // for std::forward 6 7 namespace std { 8 namespace __lldb { 9 10 #if __has_cpp_attribute(msvc::no_unique_address) 11 #define _LLDB_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] 12 #elif __has_cpp_attribute(no_unique_address) 13 #define _LLDB_NO_UNIQUE_ADDRESS [[__no_unique_address__]] 14 #endif 15 16 #if COMPRESSED_PAIR_REV == 0 // Post-c88580c layout 17 struct __value_init_tag {}; 18 struct __default_init_tag {}; 19 20 template <class _Tp, int _Idx, 21 bool _CanBeEmptyBase = 22 std::is_empty<_Tp>::value && !std::is_final<_Tp>::value> 23 struct __compressed_pair_elem { 24 explicit __compressed_pair_elem(__default_init_tag) {} 25 explicit __compressed_pair_elem(__value_init_tag) : __value_() {} 26 27 explicit __compressed_pair_elem(_Tp __t) : __value_(__t) {} 28 29 _Tp &__get() { return __value_; } 30 31 private: 32 _Tp __value_; 33 }; 34 35 template <class _Tp, int _Idx> 36 struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp { 37 explicit __compressed_pair_elem(_Tp __t) : _Tp(__t) {} 38 explicit __compressed_pair_elem(__default_init_tag) {} 39 explicit __compressed_pair_elem(__value_init_tag) : _Tp() {} 40 41 _Tp &__get() { return *this; } 42 }; 43 44 template <class _T1, class _T2> 45 class __compressed_pair : private __compressed_pair_elem<_T1, 0>, 46 private __compressed_pair_elem<_T2, 1> { 47 public: 48 using _Base1 = __compressed_pair_elem<_T1, 0>; 49 using _Base2 = __compressed_pair_elem<_T2, 1>; 50 51 explicit __compressed_pair(_T1 __t1, _T2 __t2) : _Base1(__t1), _Base2(__t2) {} 52 explicit __compressed_pair() 53 : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {} 54 55 template <class _U1, class _U2> 56 explicit __compressed_pair(_U1 &&__t1, _U2 &&__t2) 57 : _Base1(std::forward<_U1>(__t1)), _Base2(std::forward<_U2>(__t2)) {} 58 59 _T1 &first() { return static_cast<_Base1 &>(*this).__get(); } 60 }; 61 #elif COMPRESSED_PAIR_REV == 1 62 // From libc++ datasizeof.h 63 template <class _Tp> struct _FirstPaddingByte { 64 _LLDB_NO_UNIQUE_ADDRESS _Tp __v_; 65 char __first_padding_byte_; 66 }; 67 68 template <class _Tp> 69 inline const size_t __datasizeof_v = 70 __builtin_offsetof(_FirstPaddingByte<_Tp>, __first_padding_byte_); 71 72 template <class _Tp> 73 struct __lldb_is_final : public integral_constant<bool, __is_final(_Tp)> {}; 74 75 template <class _ToPad> class __compressed_pair_padding { 76 char __padding_[((is_empty<_ToPad>::value && 77 !__lldb_is_final<_ToPad>::value) || 78 is_reference<_ToPad>::value) 79 ? 0 80 : sizeof(_ToPad) - __datasizeof_v<_ToPad>]; 81 }; 82 83 #define _LLDB_COMPRESSED_PAIR(T1, Initializer1, T2, Initializer2) \ 84 [[__gnu__::__aligned__( \ 85 alignof(T2))]] _LLDB_NO_UNIQUE_ADDRESS T1 Initializer1; \ 86 _LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T1> __padding1_; \ 87 _LLDB_NO_UNIQUE_ADDRESS T2 Initializer2; \ 88 _LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T2> __padding2_; 89 90 #define _LLDB_COMPRESSED_TRIPLE(T1, Initializer1, T2, Initializer2, T3, \ 91 Initializer3) \ 92 [[using __gnu__: __aligned__(alignof(T2)), \ 93 __aligned__(alignof(T3))]] _LLDB_NO_UNIQUE_ADDRESS T1 Initializer1; \ 94 _LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T1> __padding1_; \ 95 _LLDB_NO_UNIQUE_ADDRESS T2 Initializer2; \ 96 _LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T2> __padding2_; \ 97 _LLDB_NO_UNIQUE_ADDRESS T3 Initializer3; \ 98 _LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T3> __padding3_; 99 #elif COMPRESSED_PAIR_REV == 2 100 #define _LLDB_COMPRESSED_PAIR(T1, Name1, T2, Name2) \ 101 _LLDB_NO_UNIQUE_ADDRESS T1 Name1; \ 102 _LLDB_NO_UNIQUE_ADDRESS T2 Name2 103 104 #define _LLDB_COMPRESSED_TRIPLE(T1, Name1, T2, Name2, T3, Name3) \ 105 _LLDB_NO_UNIQUE_ADDRESS T1 Name1; \ 106 _LLDB_NO_UNIQUE_ADDRESS T2 Name2; \ 107 _LLDB_NO_UNIQUE_ADDRESS T3 Name3 108 #endif 109 } // namespace __lldb 110 } // namespace std 111 112 #endif // _H 113