xref: /llvm-project/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h (revision d148548779c2546d02b2a55e75eb8525e7b6cb2d)
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