@@ -90,20 +90,26 @@ struct _LIBCPP_TEMPLATE_VIS pair
9090 }
9191
9292 template <class _U1 , class _U2 >
93- static constexpr bool __enable_explicit () {
93+ static constexpr bool __is_pair_constructible () {
9494 return is_constructible<first_type, _U1>::value
95- && is_constructible<second_type, _U2>::value
96- && (!is_convertible<_U1, first_type>::value
97- || !is_convertible<_U2, second_type>::value);
95+ && is_constructible<second_type, _U2>::value;
9896 }
9997
10098 template <class _U1 , class _U2 >
101- static constexpr bool __enable_implicit () {
102- return is_constructible<first_type, _U1>::value
103- && is_constructible<second_type, _U2>::value
104- && is_convertible<_U1, first_type>::value
99+ static constexpr bool __is_implicit () {
100+ return is_convertible<_U1, first_type>::value
105101 && is_convertible<_U2, second_type>::value;
106102 }
103+
104+ template <class _U1 , class _U2 >
105+ static constexpr bool __enable_explicit () {
106+ return __is_pair_constructible<_U1, _U2>() && !__is_implicit<_U1, _U2>();
107+ }
108+
109+ template <class _U1 , class _U2 >
110+ static constexpr bool __enable_implicit () {
111+ return __is_pair_constructible<_U1, _U2>() && __is_implicit<_U1, _U2>();
112+ }
107113 };
108114
109115 template <bool _MaybeEnable>
@@ -198,6 +204,17 @@ struct _LIBCPP_TEMPLATE_VIS pair
198204 is_nothrow_constructible<second_type, _U2>::value))
199205 : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {}
200206
207+ #if _LIBCPP_STD_VER > 20
208+ template <class _U1 , class _U2 , __enable_if_t <
209+ _CheckArgs::template __is_pair_constructible<_U1&, _U2&>()
210+ >* = nullptr >
211+ _LIBCPP_HIDE_FROM_ABI constexpr
212+ explicit (!_CheckArgs::template __is_implicit<_U1&, _U2&>()) pair(pair<_U1, _U2>& __p)
213+ noexcept ((is_nothrow_constructible<first_type, _U1&>::value &&
214+ is_nothrow_constructible<second_type, _U2&>::value))
215+ : first(__p.first), second(__p.second) {}
216+ #endif
217+
201218 template <class _U1 , class _U2 , typename enable_if<
202219 _CheckArgs::template __enable_explicit<_U1 const &, _U2 const &>()
203220 >::type* = nullptr >
@@ -234,6 +251,18 @@ struct _LIBCPP_TEMPLATE_VIS pair
234251 is_nothrow_constructible<second_type, _U2&&>::value))
235252 : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {}
236253
254+ #if _LIBCPP_STD_VER > 20
255+ template <class _U1 , class _U2 , __enable_if_t <
256+ _CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>()
257+ >* = nullptr >
258+ _LIBCPP_HIDE_FROM_ABI constexpr
259+ explicit (!_CheckArgs::template __is_implicit<const _U1&&, const _U2&&>())
260+ pair(const pair<_U1, _U2>&& __p)
261+ noexcept (is_nothrow_constructible<first_type, const _U1&&>::value &&
262+ is_nothrow_constructible<second_type, const _U2&&>::value)
263+ : first(std::move(__p.first)), second(std::move(__p.second)) {}
264+ #endif
265+
237266 template <class _Tuple , typename enable_if<
238267 _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>()
239268 >::type* = nullptr >
@@ -286,6 +315,50 @@ struct _LIBCPP_TEMPLATE_VIS pair
286315 return *this ;
287316 }
288317
318+ #if _LIBCPP_STD_VER > 20
319+ _LIBCPP_HIDE_FROM_ABI constexpr
320+ const pair& operator =(pair const & __p) const
321+ noexcept (is_nothrow_copy_assignable_v<const first_type> &&
322+ is_nothrow_copy_assignable_v<const second_type>)
323+ requires(is_copy_assignable_v<const first_type> &&
324+ is_copy_assignable_v<const second_type>) {
325+ first = __p.first ;
326+ second = __p.second ;
327+ return *this ;
328+ }
329+
330+ _LIBCPP_HIDE_FROM_ABI constexpr
331+ const pair& operator =(pair&& __p) const
332+ noexcept (is_nothrow_assignable_v<const first_type&, first_type> &&
333+ is_nothrow_assignable_v<const second_type&, second_type>)
334+ requires(is_assignable_v<const first_type&, first_type> &&
335+ is_assignable_v<const second_type&, second_type>) {
336+ first = std::forward<first_type>(__p.first );
337+ second = std::forward<second_type>(__p.second );
338+ return *this ;
339+ }
340+
341+ template <class _U1 , class _U2 >
342+ _LIBCPP_HIDE_FROM_ABI constexpr
343+ const pair& operator =(const pair<_U1, _U2>& __p) const
344+ requires (is_assignable_v<const first_type&, const _U1&> &&
345+ is_assignable_v<const second_type&, const _U2&>) {
346+ first = __p.first ;
347+ second = __p.second ;
348+ return *this ;
349+ }
350+
351+ template <class _U1 , class _U2 >
352+ _LIBCPP_HIDE_FROM_ABI constexpr
353+ const pair& operator =(pair<_U1, _U2>&& __p) const
354+ requires (is_assignable_v<const first_type&, _U1> &&
355+ is_assignable_v<const second_type&, _U2>) {
356+ first = std::forward<_U1>(__p.first );
357+ second = std::forward<_U2>(__p.second );
358+ return *this ;
359+ }
360+ #endif // _LIBCPP_STD_VER > 20
361+
289362 template <class _Tuple , typename enable_if<
290363 _CheckTLC<_Tuple>::template __enable_assign<_Tuple>()
291364 >::type* = nullptr >
@@ -306,6 +379,18 @@ struct _LIBCPP_TEMPLATE_VIS pair
306379 swap (first, __p.first );
307380 swap (second, __p.second );
308381 }
382+
383+ #if _LIBCPP_STD_VER > 20
384+ _LIBCPP_HIDE_FROM_ABI constexpr
385+ void swap (const pair& __p) const
386+ noexcept (__is_nothrow_swappable<const first_type>::value &&
387+ __is_nothrow_swappable<const second_type>::value)
388+ {
389+ using std::swap;
390+ swap (first, __p.first );
391+ swap (second, __p.second );
392+ }
393+ #endif
309394private:
310395
311396#ifndef _LIBCPP_CXX03_LANG
@@ -422,6 +507,18 @@ swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
422507 __x.swap (__y);
423508}
424509
510+ #if _LIBCPP_STD_VER > 20
511+ template <class _T1 , class _T2 >
512+ requires (__is_swappable<const _T1>::value &&
513+ __is_swappable<const _T2>::value)
514+ _LIBCPP_HIDE_FROM_ABI constexpr
515+ void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
516+ noexcept (noexcept (__x.swap(__y)))
517+ {
518+ __x.swap (__y);
519+ }
520+ #endif
521+
425522template <class _T1 , class _T2 >
426523inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
427524pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
0 commit comments