156c4ec92SMichael Buch #ifndef STD_LLDB_COMPRESSED_PAIR_H 256c4ec92SMichael Buch #define STD_LLDB_COMPRESSED_PAIR_H 356c4ec92SMichael Buch 456c4ec92SMichael Buch #include <type_traits> 556c4ec92SMichael Buch #include <utility> // for std::forward 656c4ec92SMichael Buch 756c4ec92SMichael Buch namespace std { 856c4ec92SMichael Buch namespace __lldb { 956c4ec92SMichael Buch 10*d1485487SMichael Buch #if __has_cpp_attribute(msvc::no_unique_address) 11*d1485487SMichael Buch #define _LLDB_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] 12*d1485487SMichael Buch #elif __has_cpp_attribute(no_unique_address) 13*d1485487SMichael Buch #define _LLDB_NO_UNIQUE_ADDRESS [[__no_unique_address__]] 14*d1485487SMichael Buch #endif 15*d1485487SMichael Buch 16765e106fSMichael Buch #if COMPRESSED_PAIR_REV == 0 // Post-c88580c layout 1756c4ec92SMichael Buch struct __value_init_tag {}; 1856c4ec92SMichael Buch struct __default_init_tag {}; 1956c4ec92SMichael Buch 2056c4ec92SMichael Buch template <class _Tp, int _Idx, 2156c4ec92SMichael Buch bool _CanBeEmptyBase = 2256c4ec92SMichael Buch std::is_empty<_Tp>::value && !std::is_final<_Tp>::value> 2356c4ec92SMichael Buch struct __compressed_pair_elem { 2456c4ec92SMichael Buch explicit __compressed_pair_elem(__default_init_tag) {} 2556c4ec92SMichael Buch explicit __compressed_pair_elem(__value_init_tag) : __value_() {} 2656c4ec92SMichael Buch 2756c4ec92SMichael Buch explicit __compressed_pair_elem(_Tp __t) : __value_(__t) {} 2856c4ec92SMichael Buch 2956c4ec92SMichael Buch _Tp &__get() { return __value_; } 3056c4ec92SMichael Buch 3156c4ec92SMichael Buch private: 3256c4ec92SMichael Buch _Tp __value_; 3356c4ec92SMichael Buch }; 3456c4ec92SMichael Buch 3556c4ec92SMichael Buch template <class _Tp, int _Idx> 3656c4ec92SMichael Buch struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp { 3756c4ec92SMichael Buch explicit __compressed_pair_elem(_Tp __t) : _Tp(__t) {} 3856c4ec92SMichael Buch explicit __compressed_pair_elem(__default_init_tag) {} 3956c4ec92SMichael Buch explicit __compressed_pair_elem(__value_init_tag) : _Tp() {} 4056c4ec92SMichael Buch 4156c4ec92SMichael Buch _Tp &__get() { return *this; } 4256c4ec92SMichael Buch }; 4356c4ec92SMichael Buch 4456c4ec92SMichael Buch template <class _T1, class _T2> 4556c4ec92SMichael Buch class __compressed_pair : private __compressed_pair_elem<_T1, 0>, 4656c4ec92SMichael Buch private __compressed_pair_elem<_T2, 1> { 4756c4ec92SMichael Buch public: 4856c4ec92SMichael Buch using _Base1 = __compressed_pair_elem<_T1, 0>; 4956c4ec92SMichael Buch using _Base2 = __compressed_pair_elem<_T2, 1>; 5056c4ec92SMichael Buch 5156c4ec92SMichael Buch explicit __compressed_pair(_T1 __t1, _T2 __t2) : _Base1(__t1), _Base2(__t2) {} 5256c4ec92SMichael Buch explicit __compressed_pair() 5356c4ec92SMichael Buch : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {} 5456c4ec92SMichael Buch 5556c4ec92SMichael Buch template <class _U1, class _U2> 5656c4ec92SMichael Buch explicit __compressed_pair(_U1 &&__t1, _U2 &&__t2) 5756c4ec92SMichael Buch : _Base1(std::forward<_U1>(__t1)), _Base2(std::forward<_U2>(__t2)) {} 5856c4ec92SMichael Buch 5956c4ec92SMichael Buch _T1 &first() { return static_cast<_Base1 &>(*this).__get(); } 6056c4ec92SMichael Buch }; 61765e106fSMichael Buch #elif COMPRESSED_PAIR_REV == 1 62765e106fSMichael Buch // From libc++ datasizeof.h 63765e106fSMichael Buch template <class _Tp> struct _FirstPaddingByte { 64*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS _Tp __v_; 65765e106fSMichael Buch char __first_padding_byte_; 66765e106fSMichael Buch }; 67765e106fSMichael Buch 68765e106fSMichael Buch template <class _Tp> 69765e106fSMichael Buch inline const size_t __datasizeof_v = 70765e106fSMichael Buch __builtin_offsetof(_FirstPaddingByte<_Tp>, __first_padding_byte_); 71765e106fSMichael Buch 72765e106fSMichael Buch template <class _Tp> 73765e106fSMichael Buch struct __lldb_is_final : public integral_constant<bool, __is_final(_Tp)> {}; 74765e106fSMichael Buch 75765e106fSMichael Buch template <class _ToPad> class __compressed_pair_padding { 76765e106fSMichael Buch char __padding_[((is_empty<_ToPad>::value && 77765e106fSMichael Buch !__lldb_is_final<_ToPad>::value) || 78765e106fSMichael Buch is_reference<_ToPad>::value) 79765e106fSMichael Buch ? 0 80765e106fSMichael Buch : sizeof(_ToPad) - __datasizeof_v<_ToPad>]; 81765e106fSMichael Buch }; 82765e106fSMichael Buch 83765e106fSMichael Buch #define _LLDB_COMPRESSED_PAIR(T1, Initializer1, T2, Initializer2) \ 84*d1485487SMichael Buch [[__gnu__::__aligned__( \ 85*d1485487SMichael Buch alignof(T2))]] _LLDB_NO_UNIQUE_ADDRESS T1 Initializer1; \ 86*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T1> __padding1_; \ 87*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS T2 Initializer2; \ 88*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T2> __padding2_; 89765e106fSMichael Buch 90765e106fSMichael Buch #define _LLDB_COMPRESSED_TRIPLE(T1, Initializer1, T2, Initializer2, T3, \ 91765e106fSMichael Buch Initializer3) \ 92765e106fSMichael Buch [[using __gnu__: __aligned__(alignof(T2)), \ 93*d1485487SMichael Buch __aligned__(alignof(T3))]] _LLDB_NO_UNIQUE_ADDRESS T1 Initializer1; \ 94*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T1> __padding1_; \ 95*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS T2 Initializer2; \ 96*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T2> __padding2_; \ 97*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS T3 Initializer3; \ 98*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS __compressed_pair_padding<T3> __padding3_; 99765e106fSMichael Buch #elif COMPRESSED_PAIR_REV == 2 100765e106fSMichael Buch #define _LLDB_COMPRESSED_PAIR(T1, Name1, T2, Name2) \ 101*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS T1 Name1; \ 102*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS T2 Name2 103765e106fSMichael Buch 104765e106fSMichael Buch #define _LLDB_COMPRESSED_TRIPLE(T1, Name1, T2, Name2, T3, Name3) \ 105*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS T1 Name1; \ 106*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS T2 Name2; \ 107*d1485487SMichael Buch _LLDB_NO_UNIQUE_ADDRESS T3 Name3 108765e106fSMichael Buch #endif 10956c4ec92SMichael Buch } // namespace __lldb 11056c4ec92SMichael Buch } // namespace std 11156c4ec92SMichael Buch 11256c4ec92SMichael Buch #endif // _H 113