32
32
#include < __type_traits/is_implicitly_default_constructible.h>
33
33
#include < __type_traits/is_nothrow_assignable.h>
34
34
#include < __type_traits/is_nothrow_constructible.h>
35
+ #include < __type_traits/is_reference.h>
35
36
#include < __type_traits/is_same.h>
36
37
#include < __type_traits/is_swappable.h>
37
38
#include < __type_traits/nat.h>
@@ -74,6 +75,31 @@ struct _LIBCPP_TEMPLATE_VIS pair
74
75
_LIBCPP_HIDE_FROM_ABI pair (pair const &) = default;
75
76
_LIBCPP_HIDE_FROM_ABI pair (pair&&) = default;
76
77
78
+ // Make pair trivially copyable if we have a way to do it
79
+ static const bool __enable_defaulted_assignment_operators =
80
+ !is_reference<first_type>::value && !is_reference<second_type>::value;
81
+ #if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR)
82
+ static const bool __has_defaulted_members = __enable_defaulted_assignment_operators;
83
+
84
+ _LIBCPP_HIDE_FROM_ABI constexpr pair& operator =(const pair&)
85
+ requires __enable_defaulted_assignment_operators
86
+ = default ;
87
+
88
+ _LIBCPP_HIDE_FROM_ABI constexpr pair& operator =(pair&&)
89
+ requires __enable_defaulted_assignment_operators
90
+ = default ;
91
+ #elif __has_attribute(__enable_if__) && defined(_LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR)
92
+ static const bool __has_defaulted_members = __enable_defaulted_assignment_operators;
93
+
94
+ _LIBCPP_HIDE_FROM_ABI pair& operator =(const pair&)
95
+ __attribute__ ((__enable_if__(__enable_defaulted_assignment_operators, " " ))) = default;
96
+
97
+ _LIBCPP_HIDE_FROM_ABI pair& operator =(pair&&)
98
+ __attribute__ ((__enable_if__(__enable_defaulted_assignment_operators, " " ))) = default;
99
+ #else
100
+ static const bool __has_defaulted_members = false ;
101
+ #endif // __has_attribute(__enable_if__) && defined(_LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR)
102
+
77
103
#ifdef _LIBCPP_CXX03_LANG
78
104
_LIBCPP_HIDE_FROM_ABI pair () : first(), second() {}
79
105
@@ -129,9 +155,9 @@ struct _LIBCPP_TEMPLATE_VIS pair
129
155
typename conditional< _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
130
156
131
157
template <bool _Dummy = true , __enable_if_t <_CheckArgsDep<_Dummy>::__enable_default(), int > = 0 >
132
- explicit (!_CheckArgsDep<_Dummy>::__enable_implicit_default()) _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair()
133
- _NOEXCEPT_(
134
- is_nothrow_default_constructible<first_type>::value&& is_nothrow_default_constructible<second_type>::value)
158
+ explicit (!_CheckArgsDep<_Dummy>::__enable_implicit_default()) _LIBCPP_HIDE_FROM_ABI
159
+ _LIBCPP_CONSTEXPR pair() _NOEXCEPT_(
160
+ is_nothrow_default_constructible<first_type>::value&& is_nothrow_default_constructible<second_type>::value)
135
161
: first(), second() {}
136
162
137
163
template <bool _Dummy = true ,
@@ -150,10 +176,10 @@ struct _LIBCPP_TEMPLATE_VIS pair
150
176
class _U2 ,
151
177
# endif
152
178
__enable_if_t <_CheckArgs::template __is_pair_constructible<_U1, _U2>(), int > = 0 >
153
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit (!_CheckArgs:: template __is_implicit<_U1, _U2>())
154
- pair(_U1&& __u1, _U2&& __u2)
155
- _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
156
- is_nothrow_constructible<second_type, _U2>::value))
179
+ _LIBCPP_HIDE_FROM_ABI
180
+ _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit (!_CheckArgs:: template __is_implicit<_U1, _U2>()) pair(_U1&& __u1, _U2&& __u2)
181
+ _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
182
+ is_nothrow_constructible<second_type, _U2>::value))
157
183
: first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {
158
184
}
159
185
@@ -168,17 +194,18 @@ struct _LIBCPP_TEMPLATE_VIS pair
168
194
template <class _U1 ,
169
195
class _U2 ,
170
196
__enable_if_t <_CheckArgs::template __is_pair_constructible<_U1 const &, _U2 const &>(), int > = 0 >
171
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit (
172
- !_CheckArgs::template __is_implicit<_U1 const &, _U2 const &>()) pair(pair<_U1, _U2> const & __p)
173
- _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const &>::value &&
174
- is_nothrow_constructible<second_type, _U2 const &>::value))
197
+ _LIBCPP_HIDE_FROM_ABI
198
+ _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit (!_CheckArgs::template __is_implicit<_U1 const &, _U2 const &>())
199
+ pair(pair<_U1, _U2> const & __p)
200
+ _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const &>::value &&
201
+ is_nothrow_constructible<second_type, _U2 const &>::value))
175
202
: first(__p.first), second(__p.second) {}
176
203
177
204
template <class _U1 , class _U2 , __enable_if_t <_CheckArgs::template __is_pair_constructible<_U1, _U2>(), int > = 0 >
178
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit (!_CheckArgs:: template __is_implicit<_U1, _U2>())
179
- pair(pair<_U1, _U2>&& __p)
180
- _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
181
- is_nothrow_constructible<second_type, _U2&&>::value))
205
+ _LIBCPP_HIDE_FROM_ABI
206
+ _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit (!_CheckArgs:: template __is_implicit<_U1, _U2>()) pair(pair<_U1, _U2>&& __p)
207
+ _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
208
+ is_nothrow_constructible<second_type, _U2&&>::value))
182
209
: first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
183
210
184
211
# if _LIBCPP_STD_VER >= 23
@@ -221,18 +248,21 @@ struct _LIBCPP_TEMPLATE_VIS pair
221
248
typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
222
249
223
250
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair&
224
- operator =(__conditional_t < is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value,
225
- pair,
226
- __nat> const & __p)
251
+ operator =(__conditional_t <
252
+ !__has_defaulted_members && is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value,
253
+ pair,
254
+ __nat> const & __p)
227
255
_NOEXCEPT_ (is_nothrow_copy_assignable<first_type>::value&& is_nothrow_copy_assignable<second_type>::value) {
228
256
first = __p.first ;
229
257
second = __p.second ;
230
258
return *this ;
231
259
}
232
260
233
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator =(
234
- __conditional_t < is_move_assignable<first_type>::value && is_move_assignable<second_type>::value, pair, __nat>&&
235
- __p)
261
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair&
262
+ operator =(__conditional_t <
263
+ !__has_defaulted_members && is_move_assignable<first_type>::value && is_move_assignable<second_type>::value,
264
+ pair,
265
+ __nat>&& __p)
236
266
_NOEXCEPT_ (is_nothrow_move_assignable<first_type>::value&& is_nothrow_move_assignable<second_type>::value) {
237
267
first = std::forward<first_type>(__p.first );
238
268
second = std::forward<second_type>(__p.second );
@@ -528,9 +558,9 @@ swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x
528
558
#endif
529
559
530
560
template <class _T1 , class _T2 >
531
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
532
- pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
533
- make_pair (_T1&& __t1, _T2&& __t2) {
561
+ inline _LIBCPP_HIDE_FROM_ABI
562
+ _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
563
+ make_pair (_T1&& __t1, _T2&& __t2) {
534
564
return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>(
535
565
std::forward<_T1>(__t1), std::forward<_T2>(__t2));
536
566
}
0 commit comments