1fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric 9fe6060f1SDimitry Andric #ifndef _LIBCPP___UTILITY_PAIR_H 10fe6060f1SDimitry Andric #define _LIBCPP___UTILITY_PAIR_H 11fe6060f1SDimitry Andric 12349cc55cSDimitry Andric #include <__compare/common_comparison_category.h> 13349cc55cSDimitry Andric #include <__compare/synth_three_way.h> 1406c3fb27SDimitry Andric #include <__concepts/different_from.h> 15fe6060f1SDimitry Andric #include <__config> 1606c3fb27SDimitry Andric #include <__fwd/array.h> 1706c3fb27SDimitry Andric #include <__fwd/pair.h> 18bdd1243dSDimitry Andric #include <__fwd/tuple.h> 1906c3fb27SDimitry Andric #include <__tuple/sfinae_helpers.h> 2006c3fb27SDimitry Andric #include <__tuple/tuple_element.h> 2106c3fb27SDimitry Andric #include <__tuple/tuple_indices.h> 22*0fca6ea1SDimitry Andric #include <__tuple/tuple_like_no_subrange.h> 2306c3fb27SDimitry Andric #include <__tuple/tuple_size.h> 24bdd1243dSDimitry Andric #include <__type_traits/common_reference.h> 25bdd1243dSDimitry Andric #include <__type_traits/common_type.h> 26bdd1243dSDimitry Andric #include <__type_traits/conditional.h> 2706c3fb27SDimitry Andric #include <__type_traits/decay.h> 2806c3fb27SDimitry Andric #include <__type_traits/integral_constant.h> 29bdd1243dSDimitry Andric #include <__type_traits/is_assignable.h> 30bdd1243dSDimitry Andric #include <__type_traits/is_constructible.h> 31bdd1243dSDimitry Andric #include <__type_traits/is_convertible.h> 32bdd1243dSDimitry Andric #include <__type_traits/is_implicitly_default_constructible.h> 33bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_assignable.h> 34bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_constructible.h> 35*0fca6ea1SDimitry Andric #include <__type_traits/is_reference.h> 36bdd1243dSDimitry Andric #include <__type_traits/is_same.h> 37bdd1243dSDimitry Andric #include <__type_traits/is_swappable.h> 38*0fca6ea1SDimitry Andric #include <__type_traits/is_trivially_relocatable.h> 39bdd1243dSDimitry Andric #include <__type_traits/nat.h> 4006c3fb27SDimitry Andric #include <__type_traits/remove_cvref.h> 4106c3fb27SDimitry Andric #include <__type_traits/unwrap_ref.h> 4206c3fb27SDimitry Andric #include <__utility/declval.h> 43fe6060f1SDimitry Andric #include <__utility/forward.h> 44fe6060f1SDimitry Andric #include <__utility/move.h> 45fe6060f1SDimitry Andric #include <__utility/piecewise_construct.h> 46fe6060f1SDimitry Andric #include <cstddef> 47fe6060f1SDimitry Andric 48fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 49fe6060f1SDimitry Andric # pragma GCC system_header 50fe6060f1SDimitry Andric #endif 51fe6060f1SDimitry Andric 5206c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS 5306c3fb27SDimitry Andric #include <__undef_macros> 5406c3fb27SDimitry Andric 55fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 56fe6060f1SDimitry Andric 57fe6060f1SDimitry Andric template <class, class> 58fe6060f1SDimitry Andric struct __non_trivially_copyable_base { 59cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __non_trivially_copyable_base() _NOEXCEPT {} 6006c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI 61fe6060f1SDimitry Andric __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {} 62fe6060f1SDimitry Andric }; 6306c3fb27SDimitry Andric 64fe6060f1SDimitry Andric template <class _T1, class _T2> 65fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS pair 66fe6060f1SDimitry Andric #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) 67fe6060f1SDimitry Andric : private __non_trivially_copyable_base<_T1, _T2> 68fe6060f1SDimitry Andric #endif 69fe6060f1SDimitry Andric { 7006c3fb27SDimitry Andric using first_type = _T1; 7106c3fb27SDimitry Andric using second_type = _T2; 72fe6060f1SDimitry Andric 73fe6060f1SDimitry Andric _T1 first; 74fe6060f1SDimitry Andric _T2 second; 75fe6060f1SDimitry Andric 76*0fca6ea1SDimitry Andric using __trivially_relocatable = 77*0fca6ea1SDimitry Andric __conditional_t<__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value, 78*0fca6ea1SDimitry Andric pair, 79*0fca6ea1SDimitry Andric void>; 80*0fca6ea1SDimitry Andric 8106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default; 8206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default; 83fe6060f1SDimitry Andric 84*0fca6ea1SDimitry Andric // When we are requested for pair to be trivially copyable by the ABI macro, we use defaulted members 85*0fca6ea1SDimitry Andric // if it is both legal to do it (i.e. no references) and we have a way to actually implement it, which requires 86*0fca6ea1SDimitry Andric // the __enable_if__ attribute before C++20. 87*0fca6ea1SDimitry Andric #ifdef _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR 88*0fca6ea1SDimitry Andric // FIXME: This should really just be a static constexpr variable. It's in a struct to avoid gdb printing the value 89*0fca6ea1SDimitry Andric // when printing a pair 90*0fca6ea1SDimitry Andric struct __has_defaulted_members { 91*0fca6ea1SDimitry Andric static const bool value = !is_reference<first_type>::value && !is_reference<second_type>::value; 92*0fca6ea1SDimitry Andric }; 93*0fca6ea1SDimitry Andric # if _LIBCPP_STD_VER >= 20 94*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(const pair&) 95*0fca6ea1SDimitry Andric requires __has_defaulted_members::value 96*0fca6ea1SDimitry Andric = default; 97*0fca6ea1SDimitry Andric 98*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(pair&&) 99*0fca6ea1SDimitry Andric requires __has_defaulted_members::value 100*0fca6ea1SDimitry Andric = default; 101*0fca6ea1SDimitry Andric # elif __has_attribute(__enable_if__) 102*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair& operator=(const pair&) 103*0fca6ea1SDimitry Andric __attribute__((__enable_if__(__has_defaulted_members::value, ""))) = default; 104*0fca6ea1SDimitry Andric 105*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair& operator=(pair&&) 106*0fca6ea1SDimitry Andric __attribute__((__enable_if__(__has_defaulted_members::value, ""))) = default; 107*0fca6ea1SDimitry Andric # else 108*0fca6ea1SDimitry Andric # error "_LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR isn't supported with this compiler" 109*0fca6ea1SDimitry Andric # endif 110*0fca6ea1SDimitry Andric #else 111*0fca6ea1SDimitry Andric struct __has_defaulted_members { 112*0fca6ea1SDimitry Andric static const bool value = false; 113*0fca6ea1SDimitry Andric }; 114*0fca6ea1SDimitry Andric #endif // defined(_LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR) && __has_attribute(__enable_if__) 115*0fca6ea1SDimitry Andric 116fe6060f1SDimitry Andric #ifdef _LIBCPP_CXX03_LANG 117cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair() : first(), second() {} 118fe6060f1SDimitry Andric 119cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {} 120fe6060f1SDimitry Andric 121fe6060f1SDimitry Andric template <class _U1, class _U2> 122cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} 123fe6060f1SDimitry Andric 124cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair& operator=(pair const& __p) { 125fe6060f1SDimitry Andric first = __p.first; 126fe6060f1SDimitry Andric second = __p.second; 127fe6060f1SDimitry Andric return *this; 128fe6060f1SDimitry Andric } 12906c3fb27SDimitry Andric 13006c3fb27SDimitry Andric // Extension: This is provided in C++03 because it allows properly handling the 13106c3fb27SDimitry Andric // assignment to a pair containing references, which would be a hard 13206c3fb27SDimitry Andric // error otherwise. 133*0fca6ea1SDimitry Andric template < 134*0fca6ea1SDimitry Andric class _U1, 135cb14a3feSDimitry Andric class _U2, 136*0fca6ea1SDimitry Andric __enable_if_t<is_assignable<first_type&, _U1 const&>::value && is_assignable<second_type&, _U2 const&>::value, 137*0fca6ea1SDimitry Andric int> = 0> 138cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair& operator=(pair<_U1, _U2> const& __p) { 13906c3fb27SDimitry Andric first = __p.first; 14006c3fb27SDimitry Andric second = __p.second; 14106c3fb27SDimitry Andric return *this; 14206c3fb27SDimitry Andric } 143fe6060f1SDimitry Andric #else 144fe6060f1SDimitry Andric struct _CheckArgs { 145fe6060f1SDimitry Andric template <int&...> 146*0fca6ea1SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { 147*0fca6ea1SDimitry Andric return __is_implicitly_default_constructible<_T1>::value && __is_implicitly_default_constructible<_T2>::value; 148fe6060f1SDimitry Andric } 149fe6060f1SDimitry Andric 150fe6060f1SDimitry Andric template <int&...> 151*0fca6ea1SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_default() { 152*0fca6ea1SDimitry Andric return is_default_constructible<_T1>::value && is_default_constructible<_T2>::value; 153fe6060f1SDimitry Andric } 154fe6060f1SDimitry Andric 155fe6060f1SDimitry Andric template <class _U1, class _U2> 15606c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() { 157cb14a3feSDimitry Andric return is_constructible<first_type, _U1>::value && is_constructible<second_type, _U2>::value; 158bdd1243dSDimitry Andric } 159bdd1243dSDimitry Andric 160bdd1243dSDimitry Andric template <class _U1, class _U2> 16106c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() { 162cb14a3feSDimitry Andric return is_convertible<_U1, first_type>::value && is_convertible<_U2, second_type>::value; 163bdd1243dSDimitry Andric } 164fe6060f1SDimitry Andric }; 165fe6060f1SDimitry Andric 166fe6060f1SDimitry Andric template <bool _MaybeEnable> 167cb14a3feSDimitry Andric using _CheckArgsDep _LIBCPP_NODEBUG = 168cb14a3feSDimitry Andric typename conditional< _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type; 169fe6060f1SDimitry Andric 170*0fca6ea1SDimitry Andric template <bool _Dummy = true, __enable_if_t<_CheckArgsDep<_Dummy>::__enable_default(), int> = 0> 171*0fca6ea1SDimitry Andric explicit(!_CheckArgsDep<_Dummy>::__enable_implicit_default()) _LIBCPP_HIDE_FROM_ABI constexpr pair() noexcept( 172cb14a3feSDimitry Andric is_nothrow_default_constructible<first_type>::value && is_nothrow_default_constructible<second_type>::value) 173fe6060f1SDimitry Andric : first(), second() {} 174fe6060f1SDimitry Andric 1755f757f3fSDimitry Andric template <bool _Dummy = true, 176*0fca6ea1SDimitry Andric __enable_if_t<_CheckArgsDep<_Dummy>::template __is_pair_constructible<_T1 const&, _T2 const&>(), int> = 0> 177*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 178*0fca6ea1SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_CheckArgsDep<_Dummy>::template __is_implicit<_T1 const&, _T2 const&>()) 179*0fca6ea1SDimitry Andric pair(_T1 const& __t1, _T2 const& __t2) noexcept(is_nothrow_copy_constructible<first_type>::value && 180*0fca6ea1SDimitry Andric is_nothrow_copy_constructible<second_type>::value) 181fe6060f1SDimitry Andric : first(__t1), second(__t2) {} 182fe6060f1SDimitry Andric 183349cc55cSDimitry Andric template < 18406c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951 185cb14a3feSDimitry Andric class _U1 = _T1, 186cb14a3feSDimitry Andric class _U2 = _T2, 187349cc55cSDimitry Andric # else 188cb14a3feSDimitry Andric class _U1, 189cb14a3feSDimitry Andric class _U2, 190349cc55cSDimitry Andric # endif 191*0fca6ea1SDimitry Andric __enable_if_t<_CheckArgs::template __is_pair_constructible<_U1, _U2>(), int> = 0 > 192*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_CheckArgs::template __is_implicit<_U1, _U2>()) 193*0fca6ea1SDimitry Andric pair(_U1&& __u1, _U2&& __u2) noexcept(is_nothrow_constructible<first_type, _U1>::value && 194*0fca6ea1SDimitry Andric is_nothrow_constructible<second_type, _U2>::value) 195cb14a3feSDimitry Andric : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) { 196cb14a3feSDimitry Andric } 197fe6060f1SDimitry Andric 19806c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 199*0fca6ea1SDimitry Andric template <class _U1, class _U2, __enable_if_t<_CheckArgs::template __is_pair_constructible<_U1&, _U2&>(), int> = 0> 200cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>()) 201cb14a3feSDimitry Andric pair(pair<_U1, _U2>& __p) noexcept((is_nothrow_constructible<first_type, _U1&>::value && 202bdd1243dSDimitry Andric is_nothrow_constructible<second_type, _U2&>::value)) 203bdd1243dSDimitry Andric : first(__p.first), second(__p.second) {} 204bdd1243dSDimitry Andric # endif 205bdd1243dSDimitry Andric 206cb14a3feSDimitry Andric template <class _U1, 207cb14a3feSDimitry Andric class _U2, 208*0fca6ea1SDimitry Andric __enable_if_t<_CheckArgs::template __is_pair_constructible<_U1 const&, _U2 const&>(), int> = 0> 209*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI 210*0fca6ea1SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_CheckArgs::template __is_implicit<_U1 const&, _U2 const&>()) 211*0fca6ea1SDimitry Andric pair(pair<_U1, _U2> const& __p) noexcept(is_nothrow_constructible<first_type, _U1 const&>::value && 212*0fca6ea1SDimitry Andric is_nothrow_constructible<second_type, _U2 const&>::value) 213fe6060f1SDimitry Andric : first(__p.first), second(__p.second) {} 214fe6060f1SDimitry Andric 215*0fca6ea1SDimitry Andric template <class _U1, class _U2, __enable_if_t<_CheckArgs::template __is_pair_constructible<_U1, _U2>(), int> = 0> 216*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_CheckArgs::template __is_implicit<_U1, _U2>()) 217*0fca6ea1SDimitry Andric pair(pair<_U1, _U2>&& __p) noexcept(is_nothrow_constructible<first_type, _U1&&>::value && 218*0fca6ea1SDimitry Andric is_nothrow_constructible<second_type, _U2&&>::value) 21906c3fb27SDimitry Andric : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} 220fe6060f1SDimitry Andric 22106c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 222cb14a3feSDimitry Andric template <class _U1, 223cb14a3feSDimitry Andric class _U2, 224*0fca6ea1SDimitry Andric __enable_if_t<_CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>(), int> = 0> 225cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_CheckArgs::template __is_implicit<const _U1&&, const _U2&&>()) 226cb14a3feSDimitry Andric pair(const pair<_U1, _U2>&& __p) noexcept(is_nothrow_constructible<first_type, const _U1&&>::value && 227bdd1243dSDimitry Andric is_nothrow_constructible<second_type, const _U2&&>::value) 228bdd1243dSDimitry Andric : first(std::move(__p.first)), second(std::move(__p.second)) {} 229bdd1243dSDimitry Andric # endif 230bdd1243dSDimitry Andric 23106c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 232*0fca6ea1SDimitry Andric // TODO: Remove this workaround in LLVM 20. The bug got fixed in Clang 18. 23306c3fb27SDimitry Andric // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed. 2343bd749dbSDimitry Andric template <class _PairLike> 23506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() { 236*0fca6ea1SDimitry Andric if constexpr (__pair_like_no_subrange<_PairLike>) { 23706c3fb27SDimitry Andric return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> || 23806c3fb27SDimitry Andric !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>; 23906c3fb27SDimitry Andric } 24006c3fb27SDimitry Andric return false; 24106c3fb27SDimitry Andric } 242fe6060f1SDimitry Andric 243*0fca6ea1SDimitry Andric template <__pair_like_no_subrange _PairLike> 244*0fca6ea1SDimitry Andric requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike &&>()))> && 24506c3fb27SDimitry Andric is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike &&>()))>) 246cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>()) pair(_PairLike&& __p) 24706c3fb27SDimitry Andric : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {} 24806c3fb27SDimitry Andric # endif 249fe6060f1SDimitry Andric 250fe6060f1SDimitry Andric template <class... _Args1, class... _Args2> 25106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 252*0fca6ea1SDimitry Andric pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) noexcept( 253*0fca6ea1SDimitry Andric is_nothrow_constructible<first_type, _Args1...>::value && is_nothrow_constructible<second_type, _Args2...>::value) 254cb14a3feSDimitry Andric : pair(__pc, 255cb14a3feSDimitry Andric __first_args, 256cb14a3feSDimitry Andric __second_args, 257fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Args1)>::type(), 258fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Args2) >::type()) {} 259fe6060f1SDimitry Andric 260cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& 261*0fca6ea1SDimitry Andric operator=(__conditional_t<!__has_defaulted_members::value && is_copy_assignable<first_type>::value && 262*0fca6ea1SDimitry Andric is_copy_assignable<second_type>::value, 263cb14a3feSDimitry Andric pair, 264*0fca6ea1SDimitry Andric __nat> const& __p) noexcept(is_nothrow_copy_assignable<first_type>::value && 265*0fca6ea1SDimitry Andric is_nothrow_copy_assignable<second_type>::value) { 266fe6060f1SDimitry Andric first = __p.first; 267fe6060f1SDimitry Andric second = __p.second; 268fe6060f1SDimitry Andric return *this; 269fe6060f1SDimitry Andric } 270fe6060f1SDimitry Andric 271*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& 272*0fca6ea1SDimitry Andric operator=(__conditional_t<!__has_defaulted_members::value && is_move_assignable<first_type>::value && 273*0fca6ea1SDimitry Andric is_move_assignable<second_type>::value, 274*0fca6ea1SDimitry Andric pair, 275*0fca6ea1SDimitry Andric __nat>&& __p) noexcept(is_nothrow_move_assignable<first_type>::value && 276*0fca6ea1SDimitry Andric is_nothrow_move_assignable<second_type>::value) { 27706c3fb27SDimitry Andric first = std::forward<first_type>(__p.first); 27806c3fb27SDimitry Andric second = std::forward<second_type>(__p.second); 279fe6060f1SDimitry Andric return *this; 280fe6060f1SDimitry Andric } 281fe6060f1SDimitry Andric 282cb14a3feSDimitry Andric template < 283cb14a3feSDimitry Andric class _U1, 284cb14a3feSDimitry Andric class _U2, 285*0fca6ea1SDimitry Andric __enable_if_t<is_assignable<first_type&, _U1 const&>::value && is_assignable<second_type&, _U2 const&>::value, 286*0fca6ea1SDimitry Andric int> = 0> 287*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2> const& __p) { 288*0fca6ea1SDimitry Andric first = __p.first; 289*0fca6ea1SDimitry Andric second = __p.second; 290*0fca6ea1SDimitry Andric return *this; 291*0fca6ea1SDimitry Andric } 292*0fca6ea1SDimitry Andric 293*0fca6ea1SDimitry Andric template <class _U1, 294*0fca6ea1SDimitry Andric class _U2, 295*0fca6ea1SDimitry Andric __enable_if_t<is_assignable<first_type&, _U1>::value && is_assignable<second_type&, _U2>::value, int> = 0> 296cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2>&& __p) { 29706c3fb27SDimitry Andric first = std::forward<_U1>(__p.first); 29806c3fb27SDimitry Andric second = std::forward<_U2>(__p.second); 29906c3fb27SDimitry Andric return *this; 30006c3fb27SDimitry Andric } 30106c3fb27SDimitry Andric 30206c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 303*0fca6ea1SDimitry Andric template <class = void> 304cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair const& __p) const 305cb14a3feSDimitry Andric noexcept(is_nothrow_copy_assignable_v<const first_type> && is_nothrow_copy_assignable_v<const second_type>) 306cb14a3feSDimitry Andric requires(is_copy_assignable_v<const first_type> && is_copy_assignable_v<const second_type>) 307cb14a3feSDimitry Andric { 308bdd1243dSDimitry Andric first = __p.first; 309bdd1243dSDimitry Andric second = __p.second; 310bdd1243dSDimitry Andric return *this; 311bdd1243dSDimitry Andric } 312bdd1243dSDimitry Andric 313*0fca6ea1SDimitry Andric template <class = void> 314cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair&& __p) const 315bdd1243dSDimitry Andric noexcept(is_nothrow_assignable_v<const first_type&, first_type> && 316bdd1243dSDimitry Andric is_nothrow_assignable_v<const second_type&, second_type>) 317cb14a3feSDimitry Andric requires(is_assignable_v<const first_type&, first_type> && is_assignable_v<const second_type&, second_type>) 318cb14a3feSDimitry Andric { 319bdd1243dSDimitry Andric first = std::forward<first_type>(__p.first); 320bdd1243dSDimitry Andric second = std::forward<second_type>(__p.second); 321bdd1243dSDimitry Andric return *this; 322bdd1243dSDimitry Andric } 323bdd1243dSDimitry Andric 324bdd1243dSDimitry Andric template <class _U1, class _U2> 325cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(const pair<_U1, _U2>& __p) const 326cb14a3feSDimitry Andric requires(is_assignable_v<const first_type&, const _U1&> && is_assignable_v<const second_type&, const _U2&>) 327cb14a3feSDimitry Andric { 328bdd1243dSDimitry Andric first = __p.first; 329bdd1243dSDimitry Andric second = __p.second; 330bdd1243dSDimitry Andric return *this; 331bdd1243dSDimitry Andric } 332bdd1243dSDimitry Andric 333bdd1243dSDimitry Andric template <class _U1, class _U2> 334cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair<_U1, _U2>&& __p) const 335cb14a3feSDimitry Andric requires(is_assignable_v<const first_type&, _U1> && is_assignable_v<const second_type&, _U2>) 336cb14a3feSDimitry Andric { 337bdd1243dSDimitry Andric first = std::forward<_U1>(__p.first); 338bdd1243dSDimitry Andric second = std::forward<_U2>(__p.second); 339bdd1243dSDimitry Andric return *this; 340bdd1243dSDimitry Andric } 341bdd1243dSDimitry Andric 342*0fca6ea1SDimitry Andric template <__pair_like_no_subrange _PairLike> 343*0fca6ea1SDimitry Andric requires(__different_from<_PairLike, pair> && 34406c3fb27SDimitry Andric is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> && 34506c3fb27SDimitry Andric is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>) 34606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) { 34706c3fb27SDimitry Andric first = std::get<0>(std::forward<_PairLike>(__p)); 34806c3fb27SDimitry Andric second = std::get<1>(std::forward<_PairLike>(__p)); 349fe6060f1SDimitry Andric return *this; 350fe6060f1SDimitry Andric } 351fe6060f1SDimitry Andric 352*0fca6ea1SDimitry Andric template <__pair_like_no_subrange _PairLike> 353*0fca6ea1SDimitry Andric requires(__different_from<_PairLike, pair> && 35406c3fb27SDimitry Andric is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> && 35506c3fb27SDimitry Andric is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>) 35606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const { 35706c3fb27SDimitry Andric first = std::get<0>(std::forward<_PairLike>(__p)); 35806c3fb27SDimitry Andric second = std::get<1>(std::forward<_PairLike>(__p)); 35906c3fb27SDimitry Andric return *this; 36006c3fb27SDimitry Andric } 36106c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER >= 23 36206c3fb27SDimitry Andric 36306c3fb27SDimitry Andric // Prior to C++23, we provide an approximation of constructors and assignment operators from 36406c3fb27SDimitry Andric // pair-like types. This was historically provided as an extension. 36506c3fb27SDimitry Andric # if _LIBCPP_STD_VER < 23 36606c3fb27SDimitry Andric // from std::tuple 367*0fca6ea1SDimitry Andric template <class _U1, 368cb14a3feSDimitry Andric class _U2, 369*0fca6ea1SDimitry Andric __enable_if_t<is_convertible<_U1 const&, _T1>::value && is_convertible<_U2 const&, _T2>::value, int> = 0> 370cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(tuple<_U1, _U2> const& __p) 371cb14a3feSDimitry Andric : first(std::get<0>(__p)), second(std::get<1>(__p)) {} 37206c3fb27SDimitry Andric 373*0fca6ea1SDimitry Andric template < class _U1, 374cb14a3feSDimitry Andric class _U2, 375cb14a3feSDimitry Andric __enable_if_t<is_constructible<_T1, _U1 const&>::value && is_constructible<_T2, _U2 const&>::value && 376*0fca6ea1SDimitry Andric !(is_convertible<_U1 const&, _T1>::value && is_convertible<_U2 const&, _T2>::value), 377*0fca6ea1SDimitry Andric int> = 0> 378cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(tuple<_U1, _U2> const& __p) 379cb14a3feSDimitry Andric : first(std::get<0>(__p)), second(std::get<1>(__p)) {} 38006c3fb27SDimitry Andric 381cb14a3feSDimitry Andric template <class _U1, 382cb14a3feSDimitry Andric class _U2, 383*0fca6ea1SDimitry Andric __enable_if_t<is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value, int> = 0> 384cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(tuple<_U1, _U2>&& __p) 385cb14a3feSDimitry Andric : first(std::get<0>(std::move(__p))), second(std::get<1>(std::move(__p))) {} 38606c3fb27SDimitry Andric 387cb14a3feSDimitry Andric template <class _U1, 388cb14a3feSDimitry Andric class _U2, 389cb14a3feSDimitry Andric __enable_if_t<is_constructible<_T1, _U1>::value && is_constructible<_T2, _U2>::value && 390*0fca6ea1SDimitry Andric !(is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value) > = 0> 391cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(tuple<_U1, _U2>&& __p) 392cb14a3feSDimitry Andric : first(std::get<0>(std::move(__p))), second(std::get<1>(std::move(__p))) {} 39306c3fb27SDimitry Andric 394*0fca6ea1SDimitry Andric template <class _U1, 395cb14a3feSDimitry Andric class _U2, 396*0fca6ea1SDimitry Andric __enable_if_t<is_assignable<_T1&, _U1 const&>::value && is_assignable<_T2&, _U2 const&>::value, int> = 0> 397cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2> const& __p) { 39806c3fb27SDimitry Andric first = std::get<0>(__p); 39906c3fb27SDimitry Andric second = std::get<1>(__p); 40006c3fb27SDimitry Andric return *this; 40106c3fb27SDimitry Andric } 40206c3fb27SDimitry Andric 403cb14a3feSDimitry Andric template <class _U1, 404cb14a3feSDimitry Andric class _U2, 405*0fca6ea1SDimitry Andric __enable_if_t<is_assignable<_T1&, _U1&&>::value && is_assignable<_T2&, _U2&&>::value, int> = 0> 406cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2>&& __p) { 40706c3fb27SDimitry Andric first = std::get<0>(std::move(__p)); 40806c3fb27SDimitry Andric second = std::get<1>(std::move(__p)); 40906c3fb27SDimitry Andric return *this; 41006c3fb27SDimitry Andric } 41106c3fb27SDimitry Andric 41206c3fb27SDimitry Andric // from std::array 413*0fca6ea1SDimitry Andric template <class _Up, 414*0fca6ea1SDimitry Andric __enable_if_t<is_convertible<_Up const&, _T1>::value && is_convertible<_Up const&, _T2>::value, int> = 0> 415cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(array<_Up, 2> const& __p) : first(__p[0]), second(__p[1]) {} 41606c3fb27SDimitry Andric 417*0fca6ea1SDimitry Andric template <class _Up, 418cb14a3feSDimitry Andric __enable_if_t<is_constructible<_T1, _Up const&>::value && is_constructible<_T2, _Up const&>::value && 419*0fca6ea1SDimitry Andric !(is_convertible<_Up const&, _T1>::value && is_convertible<_Up const&, _T2>::value), 420*0fca6ea1SDimitry Andric int> = 0> 421cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(array<_Up, 2> const& __p) 422cb14a3feSDimitry Andric : first(__p[0]), second(__p[1]) {} 42306c3fb27SDimitry Andric 424*0fca6ea1SDimitry Andric template <class _Up, __enable_if_t< is_convertible<_Up, _T1>::value && is_convertible<_Up, _T2>::value, int> = 0> 425cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(array<_Up, 2>&& __p) 426cb14a3feSDimitry Andric : first(std::move(__p)[0]), second(std::move(__p)[1]) {} 42706c3fb27SDimitry Andric 428cb14a3feSDimitry Andric template <class _Up, 429cb14a3feSDimitry Andric __enable_if_t<is_constructible<_T1, _Up>::value && is_constructible<_T2, _Up>::value && 430*0fca6ea1SDimitry Andric !(is_convertible<_Up, _T1>::value && is_convertible<_Up, _T2>::value), 431*0fca6ea1SDimitry Andric int> = 0> 432cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(array<_Up, 2>&& __p) 433cb14a3feSDimitry Andric : first(std::move(__p)[0]), second(std::move(__p)[1]) {} 43406c3fb27SDimitry Andric 435*0fca6ea1SDimitry Andric template <class _Up, 436*0fca6ea1SDimitry Andric __enable_if_t<is_assignable<_T1&, _Up const&>::value && is_assignable<_T2&, _Up const&>::value, int> = 0> 437cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2> const& __p) { 43806c3fb27SDimitry Andric first = std::get<0>(__p); 43906c3fb27SDimitry Andric second = std::get<1>(__p); 44006c3fb27SDimitry Andric return *this; 44106c3fb27SDimitry Andric } 44206c3fb27SDimitry Andric 443*0fca6ea1SDimitry Andric template <class _Up, __enable_if_t<is_assignable<_T1&, _Up>::value && is_assignable<_T2&, _Up>::value, int> = 0> 444cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2>&& __p) { 44506c3fb27SDimitry Andric first = std::get<0>(std::move(__p)); 44606c3fb27SDimitry Andric second = std::get<1>(std::move(__p)); 44706c3fb27SDimitry Andric return *this; 44806c3fb27SDimitry Andric } 44906c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER < 23 45006c3fb27SDimitry Andric #endif // _LIBCPP_CXX03_LANG 45106c3fb27SDimitry Andric 452cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(pair& __p) 453*0fca6ea1SDimitry Andric _NOEXCEPT_(__is_nothrow_swappable_v<first_type>&& __is_nothrow_swappable_v<second_type>) { 45406c3fb27SDimitry Andric using std::swap; 455fe6060f1SDimitry Andric swap(first, __p.first); 456fe6060f1SDimitry Andric swap(second, __p.second); 457fe6060f1SDimitry Andric } 458bdd1243dSDimitry Andric 45906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 460cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void swap(const pair& __p) const 461*0fca6ea1SDimitry Andric noexcept(__is_nothrow_swappable_v<const first_type> && __is_nothrow_swappable_v<const second_type>) { 462bdd1243dSDimitry Andric using std::swap; 463bdd1243dSDimitry Andric swap(first, __p.first); 464bdd1243dSDimitry Andric swap(second, __p.second); 465bdd1243dSDimitry Andric } 466bdd1243dSDimitry Andric #endif 467fe6060f1SDimitry Andric 468cb14a3feSDimitry Andric private: 469fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 470fe6060f1SDimitry Andric template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> 47106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 472fe6060f1SDimitry Andric pair(piecewise_construct_t, 473cb14a3feSDimitry Andric tuple<_Args1...>& __first_args, 474cb14a3feSDimitry Andric tuple<_Args2...>& __second_args, 475cb14a3feSDimitry Andric __tuple_indices<_I1...>, 476*0fca6ea1SDimitry Andric __tuple_indices<_I2...>) 477*0fca6ea1SDimitry Andric : first(std::forward<_Args1>(std::get<_I1>(__first_args))...), 478*0fca6ea1SDimitry Andric second(std::forward<_Args2>(std::get<_I2>(__second_args))...) {} 479fe6060f1SDimitry Andric #endif 480fe6060f1SDimitry Andric }; 481fe6060f1SDimitry Andric 48206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 17 483fe6060f1SDimitry Andric template <class _T1, class _T2> 484fe6060f1SDimitry Andric pair(_T1, _T2) -> pair<_T1, _T2>; 485349cc55cSDimitry Andric #endif 486349cc55cSDimitry Andric 487349cc55cSDimitry Andric // [pairs.spec], specialized algorithms 488fe6060f1SDimitry Andric 48906c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 490cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 491cb14a3feSDimitry Andric operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 492fe6060f1SDimitry Andric return __x.first == __y.first && __x.second == __y.second; 493fe6060f1SDimitry Andric } 494fe6060f1SDimitry Andric 49506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 496349cc55cSDimitry Andric 49706c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 498cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t< __synth_three_way_result<_T1, _U1>, 49906c3fb27SDimitry Andric __synth_three_way_result<_T2, _U2> > 500cb14a3feSDimitry Andric operator<=>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 50106c3fb27SDimitry Andric if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) { 502349cc55cSDimitry Andric return __c; 503349cc55cSDimitry Andric } 50406c3fb27SDimitry Andric return std::__synth_three_way(__x.second, __y.second); 505349cc55cSDimitry Andric } 506349cc55cSDimitry Andric 50706c3fb27SDimitry Andric #else // _LIBCPP_STD_VER >= 20 508349cc55cSDimitry Andric 50906c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 510cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 511cb14a3feSDimitry Andric operator!=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 512fe6060f1SDimitry Andric return !(__x == __y); 513fe6060f1SDimitry Andric } 514fe6060f1SDimitry Andric 51506c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 516cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 517cb14a3feSDimitry Andric operator<(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 518fe6060f1SDimitry Andric return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second); 519fe6060f1SDimitry Andric } 520fe6060f1SDimitry Andric 52106c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 522cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 523cb14a3feSDimitry Andric operator>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 524fe6060f1SDimitry Andric return __y < __x; 525fe6060f1SDimitry Andric } 526fe6060f1SDimitry Andric 52706c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 528cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 529cb14a3feSDimitry Andric operator>=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 530fe6060f1SDimitry Andric return !(__x < __y); 531fe6060f1SDimitry Andric } 532fe6060f1SDimitry Andric 53306c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 534cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 535cb14a3feSDimitry Andric operator<=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 536fe6060f1SDimitry Andric return !(__y < __x); 537fe6060f1SDimitry Andric } 538fe6060f1SDimitry Andric 53906c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 54081ad6265SDimitry Andric 54106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 54281ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2, template <class> class _TQual, template <class> class _UQual> 543cb14a3feSDimitry Andric requires requires { 544cb14a3feSDimitry Andric typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>; 545cb14a3feSDimitry Andric } 54681ad6265SDimitry Andric struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> { 547cb14a3feSDimitry Andric using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>; 54881ad6265SDimitry Andric }; 54981ad6265SDimitry Andric 55081ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 55181ad6265SDimitry Andric requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; } 55281ad6265SDimitry Andric struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> { 55381ad6265SDimitry Andric using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; 55481ad6265SDimitry Andric }; 55506c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 23 556349cc55cSDimitry Andric 557*0fca6ea1SDimitry Andric template <class _T1, class _T2, __enable_if_t<__is_swappable_v<_T1> && __is_swappable_v<_T2>, int> = 0> 558cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) 559*0fca6ea1SDimitry Andric _NOEXCEPT_(__is_nothrow_swappable_v<_T1>&& __is_nothrow_swappable_v<_T2>) { 560fe6060f1SDimitry Andric __x.swap(__y); 561fe6060f1SDimitry Andric } 562fe6060f1SDimitry Andric 56306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 564bdd1243dSDimitry Andric template <class _T1, class _T2> 565*0fca6ea1SDimitry Andric requires(__is_swappable_v<const _T1> && __is_swappable_v<const _T2>) 566cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void 567cb14a3feSDimitry Andric swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x.swap(__y))) { 568bdd1243dSDimitry Andric __x.swap(__y); 569bdd1243dSDimitry Andric } 570bdd1243dSDimitry Andric #endif 571fe6060f1SDimitry Andric 572fe6060f1SDimitry Andric template <class _T1, class _T2> 573*0fca6ea1SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 574*0fca6ea1SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> 575cb14a3feSDimitry Andric make_pair(_T1&& __t1, _T2&& __t2) { 576cb14a3feSDimitry Andric return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>( 577cb14a3feSDimitry Andric std::forward<_T1>(__t1), std::forward<_T2>(__t2)); 578fe6060f1SDimitry Andric } 579fe6060f1SDimitry Andric 580fe6060f1SDimitry Andric template <class _T1, class _T2> 581cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > : public integral_constant<size_t, 2> {}; 582fe6060f1SDimitry Andric 583fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 584cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> > { 585fe6060f1SDimitry Andric static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>"); 586fe6060f1SDimitry Andric }; 587fe6060f1SDimitry Andric 588fe6060f1SDimitry Andric template <class _T1, class _T2> 589cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > { 59006c3fb27SDimitry Andric using type _LIBCPP_NODEBUG = _T1; 591fe6060f1SDimitry Andric }; 592fe6060f1SDimitry Andric 593fe6060f1SDimitry Andric template <class _T1, class _T2> 594cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > { 59506c3fb27SDimitry Andric using type _LIBCPP_NODEBUG = _T2; 596fe6060f1SDimitry Andric }; 597fe6060f1SDimitry Andric 598cb14a3feSDimitry Andric template <size_t _Ip> 599cb14a3feSDimitry Andric struct __get_pair; 600fe6060f1SDimitry Andric 601fe6060f1SDimitry Andric template <> 602cb14a3feSDimitry Andric struct __get_pair<0> { 603fe6060f1SDimitry Andric template <class _T1, class _T2> 604cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT { 605cb14a3feSDimitry Andric return __p.first; 606cb14a3feSDimitry Andric } 607fe6060f1SDimitry Andric 608fe6060f1SDimitry Andric template <class _T1, class _T2> 609cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T1& get(const pair<_T1, _T2>& __p) _NOEXCEPT { 610cb14a3feSDimitry Andric return __p.first; 611cb14a3feSDimitry Andric } 612fe6060f1SDimitry Andric 613fe6060f1SDimitry Andric template <class _T1, class _T2> 614cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT { 615cb14a3feSDimitry Andric return std::forward<_T1>(__p.first); 616cb14a3feSDimitry Andric } 617fe6060f1SDimitry Andric 618fe6060f1SDimitry Andric template <class _T1, class _T2> 619cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T1&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT { 620cb14a3feSDimitry Andric return std::forward<const _T1>(__p.first); 621cb14a3feSDimitry Andric } 622fe6060f1SDimitry Andric }; 623fe6060f1SDimitry Andric 624fe6060f1SDimitry Andric template <> 625cb14a3feSDimitry Andric struct __get_pair<1> { 626fe6060f1SDimitry Andric template <class _T1, class _T2> 627cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT { 628cb14a3feSDimitry Andric return __p.second; 629cb14a3feSDimitry Andric } 630fe6060f1SDimitry Andric 631fe6060f1SDimitry Andric template <class _T1, class _T2> 632cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T2& get(const pair<_T1, _T2>& __p) _NOEXCEPT { 633cb14a3feSDimitry Andric return __p.second; 634cb14a3feSDimitry Andric } 635fe6060f1SDimitry Andric 636fe6060f1SDimitry Andric template <class _T1, class _T2> 637cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT { 638cb14a3feSDimitry Andric return std::forward<_T2>(__p.second); 639cb14a3feSDimitry Andric } 640fe6060f1SDimitry Andric 641fe6060f1SDimitry Andric template <class _T1, class _T2> 642cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T2&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT { 643cb14a3feSDimitry Andric return std::forward<const _T2>(__p.second); 644cb14a3feSDimitry Andric } 645fe6060f1SDimitry Andric }; 646fe6060f1SDimitry Andric 647fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 648cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type& 649cb14a3feSDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT { 650fe6060f1SDimitry Andric return __get_pair<_Ip>::get(__p); 651fe6060f1SDimitry Andric } 652fe6060f1SDimitry Andric 653fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 654cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type& 655cb14a3feSDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT { 656fe6060f1SDimitry Andric return __get_pair<_Ip>::get(__p); 657fe6060f1SDimitry Andric } 658fe6060f1SDimitry Andric 659fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 660cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 661cb14a3feSDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT { 66206c3fb27SDimitry Andric return __get_pair<_Ip>::get(std::move(__p)); 663fe6060f1SDimitry Andric } 664fe6060f1SDimitry Andric 665fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 666cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 667cb14a3feSDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT { 66806c3fb27SDimitry Andric return __get_pair<_Ip>::get(std::move(__p)); 669fe6060f1SDimitry Andric } 670fe6060f1SDimitry Andric 67106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 672fe6060f1SDimitry Andric template <class _T1, class _T2> 673cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT { 674fe6060f1SDimitry Andric return __get_pair<0>::get(__p); 675fe6060f1SDimitry Andric } 676fe6060f1SDimitry Andric 677fe6060f1SDimitry Andric template <class _T1, class _T2> 678cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT { 679fe6060f1SDimitry Andric return __get_pair<0>::get(__p); 680fe6060f1SDimitry Andric } 681fe6060f1SDimitry Andric 682fe6060f1SDimitry Andric template <class _T1, class _T2> 683cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT { 68406c3fb27SDimitry Andric return __get_pair<0>::get(std::move(__p)); 685fe6060f1SDimitry Andric } 686fe6060f1SDimitry Andric 687fe6060f1SDimitry Andric template <class _T1, class _T2> 688cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT { 68906c3fb27SDimitry Andric return __get_pair<0>::get(std::move(__p)); 690fe6060f1SDimitry Andric } 691fe6060f1SDimitry Andric 692fe6060f1SDimitry Andric template <class _T1, class _T2> 693cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T2, _T1>& __p) _NOEXCEPT { 694fe6060f1SDimitry Andric return __get_pair<1>::get(__p); 695fe6060f1SDimitry Andric } 696fe6060f1SDimitry Andric 697fe6060f1SDimitry Andric template <class _T1, class _T2> 698cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T2, _T1> const& __p) _NOEXCEPT { 699fe6060f1SDimitry Andric return __get_pair<1>::get(__p); 700fe6060f1SDimitry Andric } 701fe6060f1SDimitry Andric 702fe6060f1SDimitry Andric template <class _T1, class _T2> 703cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T2, _T1>&& __p) _NOEXCEPT { 70406c3fb27SDimitry Andric return __get_pair<1>::get(std::move(__p)); 705fe6060f1SDimitry Andric } 706fe6060f1SDimitry Andric 707fe6060f1SDimitry Andric template <class _T1, class _T2> 708cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T2, _T1> const&& __p) _NOEXCEPT { 70906c3fb27SDimitry Andric return __get_pair<1>::get(std::move(__p)); 710fe6060f1SDimitry Andric } 711fe6060f1SDimitry Andric 71206c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 14 713fe6060f1SDimitry Andric 714fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 715fe6060f1SDimitry Andric 71606c3fb27SDimitry Andric _LIBCPP_POP_MACROS 71706c3fb27SDimitry Andric 718fe6060f1SDimitry Andric #endif // _LIBCPP___UTILITY_PAIR_H 719