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> 17bdd1243dSDimitry Andric #include <__fwd/get.h> 1806c3fb27SDimitry Andric #include <__fwd/pair.h> 1906c3fb27SDimitry Andric #include <__fwd/subrange.h> 20bdd1243dSDimitry Andric #include <__fwd/tuple.h> 2106c3fb27SDimitry Andric #include <__tuple/pair_like.h> 2206c3fb27SDimitry Andric #include <__tuple/sfinae_helpers.h> 2306c3fb27SDimitry Andric #include <__tuple/tuple_element.h> 2406c3fb27SDimitry Andric #include <__tuple/tuple_indices.h> 2506c3fb27SDimitry Andric #include <__tuple/tuple_size.h> 26bdd1243dSDimitry Andric #include <__type_traits/common_reference.h> 27bdd1243dSDimitry Andric #include <__type_traits/common_type.h> 28bdd1243dSDimitry Andric #include <__type_traits/conditional.h> 2906c3fb27SDimitry Andric #include <__type_traits/decay.h> 3006c3fb27SDimitry Andric #include <__type_traits/integral_constant.h> 31bdd1243dSDimitry Andric #include <__type_traits/is_assignable.h> 32bdd1243dSDimitry Andric #include <__type_traits/is_constructible.h> 33bdd1243dSDimitry Andric #include <__type_traits/is_convertible.h> 34bdd1243dSDimitry Andric #include <__type_traits/is_copy_assignable.h> 35bdd1243dSDimitry Andric #include <__type_traits/is_default_constructible.h> 36bdd1243dSDimitry Andric #include <__type_traits/is_implicitly_default_constructible.h> 37bdd1243dSDimitry Andric #include <__type_traits/is_move_assignable.h> 38bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_assignable.h> 39bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_constructible.h> 40bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_copy_assignable.h> 41bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_copy_constructible.h> 42bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_default_constructible.h> 43bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_move_assignable.h> 44bdd1243dSDimitry Andric #include <__type_traits/is_same.h> 45bdd1243dSDimitry Andric #include <__type_traits/is_swappable.h> 46bdd1243dSDimitry Andric #include <__type_traits/nat.h> 4706c3fb27SDimitry Andric #include <__type_traits/remove_cvref.h> 4806c3fb27SDimitry Andric #include <__type_traits/unwrap_ref.h> 4906c3fb27SDimitry Andric #include <__utility/declval.h> 50fe6060f1SDimitry Andric #include <__utility/forward.h> 51fe6060f1SDimitry Andric #include <__utility/move.h> 52fe6060f1SDimitry Andric #include <__utility/piecewise_construct.h> 53fe6060f1SDimitry Andric #include <cstddef> 54fe6060f1SDimitry Andric 55fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 56fe6060f1SDimitry Andric # pragma GCC system_header 57fe6060f1SDimitry Andric #endif 58fe6060f1SDimitry Andric 5906c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS 6006c3fb27SDimitry Andric #include <__undef_macros> 6106c3fb27SDimitry Andric 62fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 63fe6060f1SDimitry Andric 64fe6060f1SDimitry Andric template <class, class> 65fe6060f1SDimitry Andric struct __non_trivially_copyable_base { 66*cb14a3feSDimitry Andric _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __non_trivially_copyable_base() _NOEXCEPT {} 6706c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI 68fe6060f1SDimitry Andric __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {} 69fe6060f1SDimitry Andric }; 7006c3fb27SDimitry Andric 7106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 7206c3fb27SDimitry Andric template <class _Tp> 7306c3fb27SDimitry Andric struct __is_specialization_of_subrange : false_type {}; 7406c3fb27SDimitry Andric 7506c3fb27SDimitry Andric template <class _Iter, class _Sent, ranges::subrange_kind _Kind> 7606c3fb27SDimitry Andric struct __is_specialization_of_subrange<ranges::subrange<_Iter, _Sent, _Kind>> : true_type {}; 77fe6060f1SDimitry Andric #endif 78fe6060f1SDimitry Andric 79fe6060f1SDimitry Andric template <class _T1, class _T2> 80fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS pair 81fe6060f1SDimitry Andric #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) 82fe6060f1SDimitry Andric : private __non_trivially_copyable_base<_T1, _T2> 83fe6060f1SDimitry Andric #endif 84fe6060f1SDimitry Andric { 8506c3fb27SDimitry Andric using first_type = _T1; 8606c3fb27SDimitry Andric using second_type = _T2; 87fe6060f1SDimitry Andric 88fe6060f1SDimitry Andric _T1 first; 89fe6060f1SDimitry Andric _T2 second; 90fe6060f1SDimitry Andric 9106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default; 9206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default; 93fe6060f1SDimitry Andric 94fe6060f1SDimitry Andric #ifdef _LIBCPP_CXX03_LANG 95*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair() : first(), second() {} 96fe6060f1SDimitry Andric 97*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {} 98fe6060f1SDimitry Andric 99fe6060f1SDimitry Andric template <class _U1, class _U2> 100*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} 101fe6060f1SDimitry Andric 102*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair& operator=(pair const& __p) { 103fe6060f1SDimitry Andric first = __p.first; 104fe6060f1SDimitry Andric second = __p.second; 105fe6060f1SDimitry Andric return *this; 106fe6060f1SDimitry Andric } 10706c3fb27SDimitry Andric 10806c3fb27SDimitry Andric // Extension: This is provided in C++03 because it allows properly handling the 10906c3fb27SDimitry Andric // assignment to a pair containing references, which would be a hard 11006c3fb27SDimitry Andric // error otherwise. 111*cb14a3feSDimitry Andric template <class _U1, 112*cb14a3feSDimitry Andric class _U2, 113*cb14a3feSDimitry Andric class = __enable_if_t< is_assignable<first_type&, _U1 const&>::value && 114*cb14a3feSDimitry Andric is_assignable<second_type&, _U2 const&>::value > > 115*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI pair& operator=(pair<_U1, _U2> const& __p) { 11606c3fb27SDimitry Andric first = __p.first; 11706c3fb27SDimitry Andric second = __p.second; 11806c3fb27SDimitry Andric return *this; 11906c3fb27SDimitry Andric } 120fe6060f1SDimitry Andric #else 121fe6060f1SDimitry Andric struct _CheckArgs { 122fe6060f1SDimitry Andric template <int&...> 12306c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() { 124*cb14a3feSDimitry Andric return is_default_constructible<_T1>::value && is_default_constructible<_T2>::value && 125*cb14a3feSDimitry Andric !__enable_implicit_default<>(); 126fe6060f1SDimitry Andric } 127fe6060f1SDimitry Andric 128fe6060f1SDimitry Andric template <int&...> 12906c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { 130*cb14a3feSDimitry Andric return __is_implicitly_default_constructible<_T1>::value && __is_implicitly_default_constructible<_T2>::value; 131fe6060f1SDimitry Andric } 132fe6060f1SDimitry Andric 133fe6060f1SDimitry Andric template <class _U1, class _U2> 13406c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() { 135*cb14a3feSDimitry Andric return is_constructible<first_type, _U1>::value && is_constructible<second_type, _U2>::value; 136bdd1243dSDimitry Andric } 137bdd1243dSDimitry Andric 138bdd1243dSDimitry Andric template <class _U1, class _U2> 13906c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() { 140*cb14a3feSDimitry Andric return is_convertible<_U1, first_type>::value && is_convertible<_U2, second_type>::value; 141bdd1243dSDimitry Andric } 142bdd1243dSDimitry Andric 143bdd1243dSDimitry Andric template <class _U1, class _U2> 14406c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() { 145bdd1243dSDimitry Andric return __is_pair_constructible<_U1, _U2>() && !__is_implicit<_U1, _U2>(); 146fe6060f1SDimitry Andric } 147fe6060f1SDimitry Andric 148fe6060f1SDimitry Andric template <class _U1, class _U2> 14906c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() { 150bdd1243dSDimitry Andric return __is_pair_constructible<_U1, _U2>() && __is_implicit<_U1, _U2>(); 151fe6060f1SDimitry Andric } 152fe6060f1SDimitry Andric }; 153fe6060f1SDimitry Andric 154fe6060f1SDimitry Andric template <bool _MaybeEnable> 155*cb14a3feSDimitry Andric using _CheckArgsDep _LIBCPP_NODEBUG = 156*cb14a3feSDimitry Andric typename conditional< _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type; 157fe6060f1SDimitry Andric 1585f757f3fSDimitry Andric template <bool _Dummy = true, __enable_if_t<_CheckArgsDep<_Dummy>::__enable_explicit_default(), int> = 0> 159*cb14a3feSDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair() _NOEXCEPT_( 160*cb14a3feSDimitry Andric is_nothrow_default_constructible<first_type>::value&& is_nothrow_default_constructible<second_type>::value) 161fe6060f1SDimitry Andric : first(), second() {} 162fe6060f1SDimitry Andric 1635f757f3fSDimitry Andric template <bool _Dummy = true, __enable_if_t<_CheckArgsDep<_Dummy>::__enable_implicit_default(), int> = 0> 164*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair() _NOEXCEPT_( 165*cb14a3feSDimitry Andric is_nothrow_default_constructible<first_type>::value&& is_nothrow_default_constructible<second_type>::value) 166fe6060f1SDimitry Andric : first(), second() {} 167fe6060f1SDimitry Andric 1685f757f3fSDimitry Andric template <bool _Dummy = true, 1695f757f3fSDimitry Andric __enable_if_t<_CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>(), int> = 0> 170*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(_T1 const& __t1, _T2 const& __t2) 171*cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value&& is_nothrow_copy_constructible<second_type>::value) 172fe6060f1SDimitry Andric : first(__t1), second(__t2) {} 173fe6060f1SDimitry Andric 1745f757f3fSDimitry Andric template <bool _Dummy = true, 1755f757f3fSDimitry Andric __enable_if_t<_CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>(), int> = 0> 176*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(_T1 const& __t1, _T2 const& __t2) 177*cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value&& is_nothrow_copy_constructible<second_type>::value) 178fe6060f1SDimitry Andric : first(__t1), second(__t2) {} 179fe6060f1SDimitry Andric 180349cc55cSDimitry Andric template < 18106c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951 182*cb14a3feSDimitry Andric class _U1 = _T1, 183*cb14a3feSDimitry Andric class _U2 = _T2, 184349cc55cSDimitry Andric # else 185*cb14a3feSDimitry Andric class _U1, 186*cb14a3feSDimitry Andric class _U2, 187349cc55cSDimitry Andric # endif 188*cb14a3feSDimitry Andric __enable_if_t<_CheckArgs::template __enable_explicit<_U1, _U2>(), int> = 0 > 189*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(_U1&& __u1, _U2&& __u2) 190fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && 191fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2>::value)) 192*cb14a3feSDimitry Andric : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) { 193*cb14a3feSDimitry Andric } 194fe6060f1SDimitry Andric 195349cc55cSDimitry Andric template < 19606c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951 197*cb14a3feSDimitry Andric class _U1 = _T1, 198*cb14a3feSDimitry Andric class _U2 = _T2, 199349cc55cSDimitry Andric # else 200*cb14a3feSDimitry Andric class _U1, 201*cb14a3feSDimitry Andric class _U2, 202349cc55cSDimitry Andric # endif 203*cb14a3feSDimitry Andric __enable_if_t<_CheckArgs::template __enable_implicit<_U1, _U2>(), int> = 0 > 204*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(_U1&& __u1, _U2&& __u2) 205fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && 206fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2>::value)) 207*cb14a3feSDimitry Andric : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) { 208*cb14a3feSDimitry Andric } 209fe6060f1SDimitry Andric 21006c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 211*cb14a3feSDimitry Andric template <class _U1, 212*cb14a3feSDimitry Andric class _U2, 213*cb14a3feSDimitry Andric __enable_if_t< _CheckArgs::template __is_pair_constructible<_U1&, _U2&>() >* = nullptr> 214*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>()) 215*cb14a3feSDimitry Andric pair(pair<_U1, _U2>& __p) noexcept((is_nothrow_constructible<first_type, _U1&>::value && 216bdd1243dSDimitry Andric is_nothrow_constructible<second_type, _U2&>::value)) 217bdd1243dSDimitry Andric : first(__p.first), second(__p.second) {} 218bdd1243dSDimitry Andric # endif 219bdd1243dSDimitry Andric 220*cb14a3feSDimitry Andric template <class _U1, 221*cb14a3feSDimitry Andric class _U2, 222*cb14a3feSDimitry Andric __enable_if_t<_CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>(), int> = 0> 223*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(pair<_U1, _U2> const& __p) 224fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && 225fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2 const&>::value)) 226fe6060f1SDimitry Andric : first(__p.first), second(__p.second) {} 227fe6060f1SDimitry Andric 228*cb14a3feSDimitry Andric template <class _U1, 229*cb14a3feSDimitry Andric class _U2, 230*cb14a3feSDimitry Andric __enable_if_t<_CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>(), int> = 0> 231*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(pair<_U1, _U2> const& __p) 232fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && 233fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2 const&>::value)) 234fe6060f1SDimitry Andric : first(__p.first), second(__p.second) {} 235fe6060f1SDimitry Andric 2365f757f3fSDimitry Andric template <class _U1, class _U2, __enable_if_t<_CheckArgs::template __enable_explicit<_U1, _U2>(), int> = 0> 237*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(pair<_U1, _U2>&& __p) 238fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && 239fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2&&>::value)) 24006c3fb27SDimitry Andric : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} 241fe6060f1SDimitry Andric 2425f757f3fSDimitry Andric template <class _U1, class _U2, __enable_if_t<_CheckArgs::template __enable_implicit<_U1, _U2>(), int> = 0> 243*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(pair<_U1, _U2>&& __p) 244fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && 245fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2&&>::value)) 24606c3fb27SDimitry Andric : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} 247fe6060f1SDimitry Andric 24806c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 249*cb14a3feSDimitry Andric template <class _U1, 250*cb14a3feSDimitry Andric class _U2, 251*cb14a3feSDimitry Andric __enable_if_t< _CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>() >* = nullptr> 252*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_CheckArgs::template __is_implicit<const _U1&&, const _U2&&>()) 253*cb14a3feSDimitry Andric pair(const pair<_U1, _U2>&& __p) noexcept(is_nothrow_constructible<first_type, const _U1&&>::value && 254bdd1243dSDimitry Andric is_nothrow_constructible<second_type, const _U2&&>::value) 255bdd1243dSDimitry Andric : first(std::move(__p.first)), second(std::move(__p.second)) {} 256bdd1243dSDimitry Andric # endif 257bdd1243dSDimitry Andric 25806c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 25906c3fb27SDimitry Andric // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed. 2603bd749dbSDimitry Andric template <class _PairLike> 26106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() { 2623bd749dbSDimitry Andric if constexpr (__pair_like<_PairLike>) { 26306c3fb27SDimitry Andric return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> || 26406c3fb27SDimitry Andric !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>; 26506c3fb27SDimitry Andric } 26606c3fb27SDimitry Andric return false; 26706c3fb27SDimitry Andric } 268fe6060f1SDimitry Andric 26906c3fb27SDimitry Andric template <__pair_like _PairLike> 2705f757f3fSDimitry Andric requires(!__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && 2715f757f3fSDimitry Andric is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike &&>()))> && 27206c3fb27SDimitry Andric is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike &&>()))>) 273*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>()) pair(_PairLike&& __p) 27406c3fb27SDimitry Andric : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {} 27506c3fb27SDimitry Andric # endif 276fe6060f1SDimitry Andric 277fe6060f1SDimitry Andric template <class... _Args1, class... _Args2> 27806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 279*cb14a3feSDimitry Andric pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) 280fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value && 281fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _Args2...>::value)) 282*cb14a3feSDimitry Andric : pair(__pc, 283*cb14a3feSDimitry Andric __first_args, 284*cb14a3feSDimitry Andric __second_args, 285fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Args1)>::type(), 286fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Args2) >::type()) {} 287fe6060f1SDimitry Andric 288*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& 289*cb14a3feSDimitry Andric operator=(__conditional_t< is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value, 290*cb14a3feSDimitry Andric pair, 291*cb14a3feSDimitry Andric __nat> const& __p) 292*cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value&& is_nothrow_copy_assignable<second_type>::value) { 293fe6060f1SDimitry Andric first = __p.first; 294fe6060f1SDimitry Andric second = __p.second; 295fe6060f1SDimitry Andric return *this; 296fe6060f1SDimitry Andric } 297fe6060f1SDimitry Andric 298*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=( 299*cb14a3feSDimitry Andric __conditional_t< is_move_assignable<first_type>::value && is_move_assignable<second_type>::value, pair, __nat>&& 300*cb14a3feSDimitry Andric __p) 301*cb14a3feSDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value&& is_nothrow_move_assignable<second_type>::value) { 30206c3fb27SDimitry Andric first = std::forward<first_type>(__p.first); 30306c3fb27SDimitry Andric second = std::forward<second_type>(__p.second); 304fe6060f1SDimitry Andric return *this; 305fe6060f1SDimitry Andric } 306fe6060f1SDimitry Andric 307*cb14a3feSDimitry Andric template <class _U1, 308*cb14a3feSDimitry Andric class _U2, 309*cb14a3feSDimitry Andric __enable_if_t< is_assignable<first_type&, _U1 const&>::value && 310*cb14a3feSDimitry Andric is_assignable<second_type&, _U2 const&>::value >* = nullptr> 311*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2> const& __p) { 31206c3fb27SDimitry Andric first = __p.first; 31306c3fb27SDimitry Andric second = __p.second; 31406c3fb27SDimitry Andric return *this; 31506c3fb27SDimitry Andric } 31606c3fb27SDimitry Andric 317*cb14a3feSDimitry Andric template < 318*cb14a3feSDimitry Andric class _U1, 319*cb14a3feSDimitry Andric class _U2, 320*cb14a3feSDimitry Andric __enable_if_t< is_assignable<first_type&, _U1>::value && is_assignable<second_type&, _U2>::value >* = nullptr> 321*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2>&& __p) { 32206c3fb27SDimitry Andric first = std::forward<_U1>(__p.first); 32306c3fb27SDimitry Andric second = std::forward<_U2>(__p.second); 32406c3fb27SDimitry Andric return *this; 32506c3fb27SDimitry Andric } 32606c3fb27SDimitry Andric 32706c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 328*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair const& __p) const 329*cb14a3feSDimitry Andric noexcept(is_nothrow_copy_assignable_v<const first_type> && is_nothrow_copy_assignable_v<const second_type>) 330*cb14a3feSDimitry Andric requires(is_copy_assignable_v<const first_type> && is_copy_assignable_v<const second_type>) 331*cb14a3feSDimitry Andric { 332bdd1243dSDimitry Andric first = __p.first; 333bdd1243dSDimitry Andric second = __p.second; 334bdd1243dSDimitry Andric return *this; 335bdd1243dSDimitry Andric } 336bdd1243dSDimitry Andric 337*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair&& __p) const 338bdd1243dSDimitry Andric noexcept(is_nothrow_assignable_v<const first_type&, first_type> && 339bdd1243dSDimitry Andric is_nothrow_assignable_v<const second_type&, second_type>) 340*cb14a3feSDimitry Andric requires(is_assignable_v<const first_type&, first_type> && is_assignable_v<const second_type&, second_type>) 341*cb14a3feSDimitry Andric { 342bdd1243dSDimitry Andric first = std::forward<first_type>(__p.first); 343bdd1243dSDimitry Andric second = std::forward<second_type>(__p.second); 344bdd1243dSDimitry Andric return *this; 345bdd1243dSDimitry Andric } 346bdd1243dSDimitry Andric 347bdd1243dSDimitry Andric template <class _U1, class _U2> 348*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(const pair<_U1, _U2>& __p) const 349*cb14a3feSDimitry Andric requires(is_assignable_v<const first_type&, const _U1&> && is_assignable_v<const second_type&, const _U2&>) 350*cb14a3feSDimitry Andric { 351bdd1243dSDimitry Andric first = __p.first; 352bdd1243dSDimitry Andric second = __p.second; 353bdd1243dSDimitry Andric return *this; 354bdd1243dSDimitry Andric } 355bdd1243dSDimitry Andric 356bdd1243dSDimitry Andric template <class _U1, class _U2> 357*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair<_U1, _U2>&& __p) const 358*cb14a3feSDimitry Andric requires(is_assignable_v<const first_type&, _U1> && is_assignable_v<const second_type&, _U2>) 359*cb14a3feSDimitry Andric { 360bdd1243dSDimitry Andric first = std::forward<_U1>(__p.first); 361bdd1243dSDimitry Andric second = std::forward<_U2>(__p.second); 362bdd1243dSDimitry Andric return *this; 363bdd1243dSDimitry Andric } 364bdd1243dSDimitry Andric 36506c3fb27SDimitry Andric template <__pair_like _PairLike> 366*cb14a3feSDimitry Andric requires(__different_from<_PairLike, pair> && !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && 36706c3fb27SDimitry Andric is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> && 36806c3fb27SDimitry Andric is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>) 36906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) { 37006c3fb27SDimitry Andric first = std::get<0>(std::forward<_PairLike>(__p)); 37106c3fb27SDimitry Andric second = std::get<1>(std::forward<_PairLike>(__p)); 372fe6060f1SDimitry Andric return *this; 373fe6060f1SDimitry Andric } 374fe6060f1SDimitry Andric 37506c3fb27SDimitry Andric template <__pair_like _PairLike> 376*cb14a3feSDimitry Andric requires(__different_from<_PairLike, pair> && !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && 37706c3fb27SDimitry Andric is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> && 37806c3fb27SDimitry Andric is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>) 37906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const { 38006c3fb27SDimitry Andric first = std::get<0>(std::forward<_PairLike>(__p)); 38106c3fb27SDimitry Andric second = std::get<1>(std::forward<_PairLike>(__p)); 38206c3fb27SDimitry Andric return *this; 38306c3fb27SDimitry Andric } 38406c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER >= 23 38506c3fb27SDimitry Andric 38606c3fb27SDimitry Andric // Prior to C++23, we provide an approximation of constructors and assignment operators from 38706c3fb27SDimitry Andric // pair-like types. This was historically provided as an extension. 38806c3fb27SDimitry Andric # if _LIBCPP_STD_VER < 23 38906c3fb27SDimitry Andric // from std::tuple 390*cb14a3feSDimitry Andric template < 391*cb14a3feSDimitry Andric class _U1, 392*cb14a3feSDimitry Andric class _U2, 393*cb14a3feSDimitry Andric __enable_if_t< is_convertible<_U1 const&, _T1>::value && is_convertible<_U2 const&, _T2>::value >* = nullptr> 394*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(tuple<_U1, _U2> const& __p) 395*cb14a3feSDimitry Andric : first(std::get<0>(__p)), second(std::get<1>(__p)) {} 39606c3fb27SDimitry Andric 397*cb14a3feSDimitry Andric template < 398*cb14a3feSDimitry Andric class _U1, 399*cb14a3feSDimitry Andric class _U2, 400*cb14a3feSDimitry Andric __enable_if_t< is_constructible<_T1, _U1 const&>::value && is_constructible<_T2, _U2 const&>::value && 401*cb14a3feSDimitry Andric !(is_convertible<_U1 const&, _T1>::value && is_convertible<_U2 const&, _T2>::value) >* = nullptr> 402*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(tuple<_U1, _U2> const& __p) 403*cb14a3feSDimitry Andric : first(std::get<0>(__p)), second(std::get<1>(__p)) {} 40406c3fb27SDimitry Andric 405*cb14a3feSDimitry Andric template <class _U1, 406*cb14a3feSDimitry Andric class _U2, 407*cb14a3feSDimitry Andric __enable_if_t< is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value >* = nullptr> 408*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(tuple<_U1, _U2>&& __p) 409*cb14a3feSDimitry Andric : first(std::get<0>(std::move(__p))), second(std::get<1>(std::move(__p))) {} 41006c3fb27SDimitry Andric 411*cb14a3feSDimitry Andric template <class _U1, 412*cb14a3feSDimitry Andric class _U2, 413*cb14a3feSDimitry Andric __enable_if_t< is_constructible<_T1, _U1>::value && is_constructible<_T2, _U2>::value && 414*cb14a3feSDimitry Andric !(is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value) >* = nullptr> 415*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(tuple<_U1, _U2>&& __p) 416*cb14a3feSDimitry Andric : first(std::get<0>(std::move(__p))), second(std::get<1>(std::move(__p))) {} 41706c3fb27SDimitry Andric 418*cb14a3feSDimitry Andric template < 419*cb14a3feSDimitry Andric class _U1, 420*cb14a3feSDimitry Andric class _U2, 421*cb14a3feSDimitry Andric __enable_if_t< is_assignable<_T1&, _U1 const&>::value && is_assignable<_T2&, _U2 const&>::value >* = nullptr> 422*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2> const& __p) { 42306c3fb27SDimitry Andric first = std::get<0>(__p); 42406c3fb27SDimitry Andric second = std::get<1>(__p); 42506c3fb27SDimitry Andric return *this; 42606c3fb27SDimitry Andric } 42706c3fb27SDimitry Andric 428*cb14a3feSDimitry Andric template <class _U1, 429*cb14a3feSDimitry Andric class _U2, 430*cb14a3feSDimitry Andric __enable_if_t< is_assignable<_T1&, _U1&&>::value && is_assignable<_T2&, _U2&&>::value >* = nullptr> 431*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2>&& __p) { 43206c3fb27SDimitry Andric first = std::get<0>(std::move(__p)); 43306c3fb27SDimitry Andric second = std::get<1>(std::move(__p)); 43406c3fb27SDimitry Andric return *this; 43506c3fb27SDimitry Andric } 43606c3fb27SDimitry Andric 43706c3fb27SDimitry Andric // from std::array 438*cb14a3feSDimitry Andric template < 439*cb14a3feSDimitry Andric class _Up, 440*cb14a3feSDimitry Andric __enable_if_t< is_convertible<_Up const&, _T1>::value && is_convertible<_Up const&, _T2>::value >* = nullptr> 441*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(array<_Up, 2> const& __p) : first(__p[0]), second(__p[1]) {} 44206c3fb27SDimitry Andric 443*cb14a3feSDimitry Andric template < 444*cb14a3feSDimitry Andric class _Up, 445*cb14a3feSDimitry Andric __enable_if_t< is_constructible<_T1, _Up const&>::value && is_constructible<_T2, _Up const&>::value && 446*cb14a3feSDimitry Andric !(is_convertible<_Up const&, _T1>::value && is_convertible<_Up const&, _T2>::value) >* = nullptr> 447*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(array<_Up, 2> const& __p) 448*cb14a3feSDimitry Andric : first(__p[0]), second(__p[1]) {} 44906c3fb27SDimitry Andric 450*cb14a3feSDimitry Andric template <class _Up, __enable_if_t< is_convertible<_Up, _T1>::value && is_convertible<_Up, _T2>::value >* = nullptr> 451*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(array<_Up, 2>&& __p) 452*cb14a3feSDimitry Andric : first(std::move(__p)[0]), second(std::move(__p)[1]) {} 45306c3fb27SDimitry Andric 454*cb14a3feSDimitry Andric template <class _Up, 455*cb14a3feSDimitry Andric __enable_if_t< is_constructible<_T1, _Up>::value && is_constructible<_T2, _Up>::value && 456*cb14a3feSDimitry Andric !(is_convertible<_Up, _T1>::value && is_convertible<_Up, _T2>::value) >* = nullptr> 457*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(array<_Up, 2>&& __p) 458*cb14a3feSDimitry Andric : first(std::move(__p)[0]), second(std::move(__p)[1]) {} 45906c3fb27SDimitry Andric 460*cb14a3feSDimitry Andric template < 461*cb14a3feSDimitry Andric class _Up, 462*cb14a3feSDimitry Andric __enable_if_t< is_assignable<_T1&, _Up const&>::value && is_assignable<_T2&, _Up const&>::value >* = nullptr> 463*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2> const& __p) { 46406c3fb27SDimitry Andric first = std::get<0>(__p); 46506c3fb27SDimitry Andric second = std::get<1>(__p); 46606c3fb27SDimitry Andric return *this; 46706c3fb27SDimitry Andric } 46806c3fb27SDimitry Andric 469*cb14a3feSDimitry Andric template <class _Up, __enable_if_t< is_assignable<_T1&, _Up>::value && is_assignable<_T2&, _Up>::value >* = nullptr> 470*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2>&& __p) { 47106c3fb27SDimitry Andric first = std::get<0>(std::move(__p)); 47206c3fb27SDimitry Andric second = std::get<1>(std::move(__p)); 47306c3fb27SDimitry Andric return *this; 47406c3fb27SDimitry Andric } 47506c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER < 23 47606c3fb27SDimitry Andric #endif // _LIBCPP_CXX03_LANG 47706c3fb27SDimitry Andric 478*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(pair& __p) 479*cb14a3feSDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<first_type>::value&& __is_nothrow_swappable<second_type>::value) { 48006c3fb27SDimitry Andric using std::swap; 481fe6060f1SDimitry Andric swap(first, __p.first); 482fe6060f1SDimitry Andric swap(second, __p.second); 483fe6060f1SDimitry Andric } 484bdd1243dSDimitry Andric 48506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 486*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void swap(const pair& __p) const 487*cb14a3feSDimitry Andric noexcept(__is_nothrow_swappable<const first_type>::value && __is_nothrow_swappable<const second_type>::value) { 488bdd1243dSDimitry Andric using std::swap; 489bdd1243dSDimitry Andric swap(first, __p.first); 490bdd1243dSDimitry Andric swap(second, __p.second); 491bdd1243dSDimitry Andric } 492bdd1243dSDimitry Andric #endif 493fe6060f1SDimitry Andric 494*cb14a3feSDimitry Andric private: 495fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 496fe6060f1SDimitry Andric template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> 49706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 498fe6060f1SDimitry Andric pair(piecewise_construct_t, 499*cb14a3feSDimitry Andric tuple<_Args1...>& __first_args, 500*cb14a3feSDimitry Andric tuple<_Args2...>& __second_args, 501*cb14a3feSDimitry Andric __tuple_indices<_I1...>, 502*cb14a3feSDimitry Andric __tuple_indices<_I2...>); 503fe6060f1SDimitry Andric #endif 504fe6060f1SDimitry Andric }; 505fe6060f1SDimitry Andric 50606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 17 507fe6060f1SDimitry Andric template <class _T1, class _T2> 508fe6060f1SDimitry Andric pair(_T1, _T2) -> pair<_T1, _T2>; 509349cc55cSDimitry Andric #endif 510349cc55cSDimitry Andric 511349cc55cSDimitry Andric // [pairs.spec], specialized algorithms 512fe6060f1SDimitry Andric 51306c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 514*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 515*cb14a3feSDimitry Andric operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 516fe6060f1SDimitry Andric return __x.first == __y.first && __x.second == __y.second; 517fe6060f1SDimitry Andric } 518fe6060f1SDimitry Andric 51906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 520349cc55cSDimitry Andric 52106c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 522*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t< __synth_three_way_result<_T1, _U1>, 52306c3fb27SDimitry Andric __synth_three_way_result<_T2, _U2> > 524*cb14a3feSDimitry Andric operator<=>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 52506c3fb27SDimitry Andric if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) { 526349cc55cSDimitry Andric return __c; 527349cc55cSDimitry Andric } 52806c3fb27SDimitry Andric return std::__synth_three_way(__x.second, __y.second); 529349cc55cSDimitry Andric } 530349cc55cSDimitry Andric 53106c3fb27SDimitry Andric #else // _LIBCPP_STD_VER >= 20 532349cc55cSDimitry Andric 53306c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 534*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 535*cb14a3feSDimitry Andric operator!=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 536fe6060f1SDimitry Andric return !(__x == __y); 537fe6060f1SDimitry Andric } 538fe6060f1SDimitry Andric 53906c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 540*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 541*cb14a3feSDimitry Andric operator<(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 542fe6060f1SDimitry Andric return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second); 543fe6060f1SDimitry Andric } 544fe6060f1SDimitry Andric 54506c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 546*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 547*cb14a3feSDimitry Andric operator>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 548fe6060f1SDimitry Andric return __y < __x; 549fe6060f1SDimitry Andric } 550fe6060f1SDimitry Andric 55106c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 552*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 553*cb14a3feSDimitry Andric operator>=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 554fe6060f1SDimitry Andric return !(__x < __y); 555fe6060f1SDimitry Andric } 556fe6060f1SDimitry Andric 55706c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 558*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool 559*cb14a3feSDimitry Andric operator<=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) { 560fe6060f1SDimitry Andric return !(__y < __x); 561fe6060f1SDimitry Andric } 562fe6060f1SDimitry Andric 56306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 56481ad6265SDimitry Andric 56506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 56681ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2, template <class> class _TQual, template <class> class _UQual> 567*cb14a3feSDimitry Andric requires requires { 568*cb14a3feSDimitry Andric typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>; 569*cb14a3feSDimitry Andric } 57081ad6265SDimitry Andric struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> { 571*cb14a3feSDimitry Andric using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>; 57281ad6265SDimitry Andric }; 57381ad6265SDimitry Andric 57481ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 57581ad6265SDimitry Andric requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; } 57681ad6265SDimitry Andric struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> { 57781ad6265SDimitry Andric using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; 57881ad6265SDimitry Andric }; 57906c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 23 580349cc55cSDimitry Andric 5815f757f3fSDimitry Andric template <class _T1, class _T2, __enable_if_t<__is_swappable<_T1>::value && __is_swappable<_T2>::value, int> = 0> 582*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) 583*cb14a3feSDimitry Andric _NOEXCEPT_((__is_nothrow_swappable<_T1>::value && __is_nothrow_swappable<_T2>::value)) { 584fe6060f1SDimitry Andric __x.swap(__y); 585fe6060f1SDimitry Andric } 586fe6060f1SDimitry Andric 58706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 588bdd1243dSDimitry Andric template <class _T1, class _T2> 589*cb14a3feSDimitry Andric requires(__is_swappable<const _T1>::value && __is_swappable<const _T2>::value) 590*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void 591*cb14a3feSDimitry Andric swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x.swap(__y))) { 592bdd1243dSDimitry Andric __x.swap(__y); 593bdd1243dSDimitry Andric } 594bdd1243dSDimitry Andric #endif 595fe6060f1SDimitry Andric 596fe6060f1SDimitry Andric template <class _T1, class _T2> 59706c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 598fe6060f1SDimitry Andric pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> 599*cb14a3feSDimitry Andric make_pair(_T1&& __t1, _T2&& __t2) { 600*cb14a3feSDimitry Andric return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>( 601*cb14a3feSDimitry Andric std::forward<_T1>(__t1), std::forward<_T2>(__t2)); 602fe6060f1SDimitry Andric } 603fe6060f1SDimitry Andric 604fe6060f1SDimitry Andric template <class _T1, class _T2> 605*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > : public integral_constant<size_t, 2> {}; 606fe6060f1SDimitry Andric 607fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 608*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> > { 609fe6060f1SDimitry Andric static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>"); 610fe6060f1SDimitry Andric }; 611fe6060f1SDimitry Andric 612fe6060f1SDimitry Andric template <class _T1, class _T2> 613*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > { 61406c3fb27SDimitry Andric using type _LIBCPP_NODEBUG = _T1; 615fe6060f1SDimitry Andric }; 616fe6060f1SDimitry Andric 617fe6060f1SDimitry Andric template <class _T1, class _T2> 618*cb14a3feSDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > { 61906c3fb27SDimitry Andric using type _LIBCPP_NODEBUG = _T2; 620fe6060f1SDimitry Andric }; 621fe6060f1SDimitry Andric 622*cb14a3feSDimitry Andric template <size_t _Ip> 623*cb14a3feSDimitry Andric struct __get_pair; 624fe6060f1SDimitry Andric 625fe6060f1SDimitry Andric template <> 626*cb14a3feSDimitry Andric struct __get_pair<0> { 627fe6060f1SDimitry Andric template <class _T1, class _T2> 628*cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT { 629*cb14a3feSDimitry Andric return __p.first; 630*cb14a3feSDimitry Andric } 631fe6060f1SDimitry Andric 632fe6060f1SDimitry Andric template <class _T1, class _T2> 633*cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T1& get(const pair<_T1, _T2>& __p) _NOEXCEPT { 634*cb14a3feSDimitry Andric return __p.first; 635*cb14a3feSDimitry Andric } 636fe6060f1SDimitry Andric 637fe6060f1SDimitry Andric template <class _T1, class _T2> 638*cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT { 639*cb14a3feSDimitry Andric return std::forward<_T1>(__p.first); 640*cb14a3feSDimitry Andric } 641fe6060f1SDimitry Andric 642fe6060f1SDimitry Andric template <class _T1, class _T2> 643*cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T1&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT { 644*cb14a3feSDimitry Andric return std::forward<const _T1>(__p.first); 645*cb14a3feSDimitry Andric } 646fe6060f1SDimitry Andric }; 647fe6060f1SDimitry Andric 648fe6060f1SDimitry Andric template <> 649*cb14a3feSDimitry Andric struct __get_pair<1> { 650fe6060f1SDimitry Andric template <class _T1, class _T2> 651*cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT { 652*cb14a3feSDimitry Andric return __p.second; 653*cb14a3feSDimitry Andric } 654fe6060f1SDimitry Andric 655fe6060f1SDimitry Andric template <class _T1, class _T2> 656*cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T2& get(const pair<_T1, _T2>& __p) _NOEXCEPT { 657*cb14a3feSDimitry Andric return __p.second; 658*cb14a3feSDimitry Andric } 659fe6060f1SDimitry Andric 660fe6060f1SDimitry Andric template <class _T1, class _T2> 661*cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT { 662*cb14a3feSDimitry Andric return std::forward<_T2>(__p.second); 663*cb14a3feSDimitry Andric } 664fe6060f1SDimitry Andric 665fe6060f1SDimitry Andric template <class _T1, class _T2> 666*cb14a3feSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T2&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT { 667*cb14a3feSDimitry Andric return std::forward<const _T2>(__p.second); 668*cb14a3feSDimitry Andric } 669fe6060f1SDimitry Andric }; 670fe6060f1SDimitry Andric 671fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 672*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type& 673*cb14a3feSDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT { 674fe6060f1SDimitry Andric return __get_pair<_Ip>::get(__p); 675fe6060f1SDimitry Andric } 676fe6060f1SDimitry Andric 677fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 678*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type& 679*cb14a3feSDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT { 680fe6060f1SDimitry Andric return __get_pair<_Ip>::get(__p); 681fe6060f1SDimitry Andric } 682fe6060f1SDimitry Andric 683fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 684*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 685*cb14a3feSDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT { 68606c3fb27SDimitry Andric return __get_pair<_Ip>::get(std::move(__p)); 687fe6060f1SDimitry Andric } 688fe6060f1SDimitry Andric 689fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 690*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 691*cb14a3feSDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT { 69206c3fb27SDimitry Andric return __get_pair<_Ip>::get(std::move(__p)); 693fe6060f1SDimitry Andric } 694fe6060f1SDimitry Andric 69506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 696fe6060f1SDimitry Andric template <class _T1, class _T2> 697*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT { 698fe6060f1SDimitry Andric return __get_pair<0>::get(__p); 699fe6060f1SDimitry Andric } 700fe6060f1SDimitry Andric 701fe6060f1SDimitry Andric template <class _T1, class _T2> 702*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT { 703fe6060f1SDimitry Andric return __get_pair<0>::get(__p); 704fe6060f1SDimitry Andric } 705fe6060f1SDimitry Andric 706fe6060f1SDimitry Andric template <class _T1, class _T2> 707*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT { 70806c3fb27SDimitry Andric return __get_pair<0>::get(std::move(__p)); 709fe6060f1SDimitry Andric } 710fe6060f1SDimitry Andric 711fe6060f1SDimitry Andric template <class _T1, class _T2> 712*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT { 71306c3fb27SDimitry Andric return __get_pair<0>::get(std::move(__p)); 714fe6060f1SDimitry Andric } 715fe6060f1SDimitry Andric 716fe6060f1SDimitry Andric template <class _T1, class _T2> 717*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T2, _T1>& __p) _NOEXCEPT { 718fe6060f1SDimitry Andric return __get_pair<1>::get(__p); 719fe6060f1SDimitry Andric } 720fe6060f1SDimitry Andric 721fe6060f1SDimitry Andric template <class _T1, class _T2> 722*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T2, _T1> const& __p) _NOEXCEPT { 723fe6060f1SDimitry Andric return __get_pair<1>::get(__p); 724fe6060f1SDimitry Andric } 725fe6060f1SDimitry Andric 726fe6060f1SDimitry Andric template <class _T1, class _T2> 727*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T2, _T1>&& __p) _NOEXCEPT { 72806c3fb27SDimitry Andric return __get_pair<1>::get(std::move(__p)); 729fe6060f1SDimitry Andric } 730fe6060f1SDimitry Andric 731fe6060f1SDimitry Andric template <class _T1, class _T2> 732*cb14a3feSDimitry Andric inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T2, _T1> const&& __p) _NOEXCEPT { 73306c3fb27SDimitry Andric return __get_pair<1>::get(std::move(__p)); 734fe6060f1SDimitry Andric } 735fe6060f1SDimitry Andric 73606c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 14 737fe6060f1SDimitry Andric 738fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 739fe6060f1SDimitry Andric 74006c3fb27SDimitry Andric _LIBCPP_POP_MACROS 74106c3fb27SDimitry Andric 742fe6060f1SDimitry Andric #endif // _LIBCPP___UTILITY_PAIR_H 743