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