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 { 6606c3fb27SDimitry Andric _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI 67fe6060f1SDimitry Andric __non_trivially_copyable_base() _NOEXCEPT {} 6806c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI 69fe6060f1SDimitry Andric __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {} 70fe6060f1SDimitry Andric }; 7106c3fb27SDimitry Andric 7206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 7306c3fb27SDimitry Andric template <class _Tp> 7406c3fb27SDimitry Andric struct __is_specialization_of_subrange : false_type {}; 7506c3fb27SDimitry Andric 7606c3fb27SDimitry Andric template <class _Iter, class _Sent, ranges::subrange_kind _Kind> 7706c3fb27SDimitry Andric struct __is_specialization_of_subrange<ranges::subrange<_Iter, _Sent, _Kind>> : true_type {}; 78fe6060f1SDimitry Andric #endif 79fe6060f1SDimitry Andric 80fe6060f1SDimitry Andric template <class _T1, class _T2> 81fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS pair 82fe6060f1SDimitry Andric #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) 83fe6060f1SDimitry Andric : private __non_trivially_copyable_base<_T1, _T2> 84fe6060f1SDimitry Andric #endif 85fe6060f1SDimitry Andric { 8606c3fb27SDimitry Andric using first_type = _T1; 8706c3fb27SDimitry Andric using second_type = _T2; 88fe6060f1SDimitry Andric 89fe6060f1SDimitry Andric _T1 first; 90fe6060f1SDimitry Andric _T2 second; 91fe6060f1SDimitry Andric 9206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default; 9306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default; 94fe6060f1SDimitry Andric 95fe6060f1SDimitry Andric #ifdef _LIBCPP_CXX03_LANG 9606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 97fe6060f1SDimitry Andric pair() : first(), second() {} 98fe6060f1SDimitry Andric 9906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 100fe6060f1SDimitry Andric pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {} 101fe6060f1SDimitry Andric 102fe6060f1SDimitry Andric template <class _U1, class _U2> 10306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 104fe6060f1SDimitry Andric pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} 105fe6060f1SDimitry Andric 10606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 107fe6060f1SDimitry Andric pair& operator=(pair const& __p) { 108fe6060f1SDimitry Andric first = __p.first; 109fe6060f1SDimitry Andric second = __p.second; 110fe6060f1SDimitry Andric return *this; 111fe6060f1SDimitry Andric } 11206c3fb27SDimitry Andric 11306c3fb27SDimitry Andric // Extension: This is provided in C++03 because it allows properly handling the 11406c3fb27SDimitry Andric // assignment to a pair containing references, which would be a hard 11506c3fb27SDimitry Andric // error otherwise. 11606c3fb27SDimitry Andric template <class _U1, class _U2, class = __enable_if_t< 11706c3fb27SDimitry Andric is_assignable<first_type&, _U1 const&>::value && 11806c3fb27SDimitry Andric is_assignable<second_type&, _U2 const&>::value 11906c3fb27SDimitry Andric > > 12006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 12106c3fb27SDimitry Andric pair& operator=(pair<_U1, _U2> const& __p) { 12206c3fb27SDimitry Andric first = __p.first; 12306c3fb27SDimitry Andric second = __p.second; 12406c3fb27SDimitry Andric return *this; 12506c3fb27SDimitry Andric } 126fe6060f1SDimitry Andric #else 127fe6060f1SDimitry Andric struct _CheckArgs { 128fe6060f1SDimitry Andric template <int&...> 12906c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() { 130fe6060f1SDimitry Andric return is_default_constructible<_T1>::value 131fe6060f1SDimitry Andric && is_default_constructible<_T2>::value 132fe6060f1SDimitry Andric && !__enable_implicit_default<>(); 133fe6060f1SDimitry Andric } 134fe6060f1SDimitry Andric 135fe6060f1SDimitry Andric template <int&...> 13606c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { 137fe6060f1SDimitry Andric return __is_implicitly_default_constructible<_T1>::value 138fe6060f1SDimitry Andric && __is_implicitly_default_constructible<_T2>::value; 139fe6060f1SDimitry Andric } 140fe6060f1SDimitry Andric 141fe6060f1SDimitry Andric template <class _U1, class _U2> 14206c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() { 143fe6060f1SDimitry Andric return is_constructible<first_type, _U1>::value 144bdd1243dSDimitry Andric && is_constructible<second_type, _U2>::value; 145bdd1243dSDimitry Andric } 146bdd1243dSDimitry Andric 147bdd1243dSDimitry Andric template <class _U1, class _U2> 14806c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() { 149bdd1243dSDimitry Andric return is_convertible<_U1, first_type>::value 150bdd1243dSDimitry Andric && is_convertible<_U2, second_type>::value; 151bdd1243dSDimitry Andric } 152bdd1243dSDimitry Andric 153bdd1243dSDimitry Andric template <class _U1, class _U2> 15406c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() { 155bdd1243dSDimitry Andric return __is_pair_constructible<_U1, _U2>() && !__is_implicit<_U1, _U2>(); 156fe6060f1SDimitry Andric } 157fe6060f1SDimitry Andric 158fe6060f1SDimitry Andric template <class _U1, class _U2> 15906c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() { 160bdd1243dSDimitry Andric return __is_pair_constructible<_U1, _U2>() && __is_implicit<_U1, _U2>(); 161fe6060f1SDimitry Andric } 162fe6060f1SDimitry Andric }; 163fe6060f1SDimitry Andric 164fe6060f1SDimitry Andric template <bool _MaybeEnable> 165349cc55cSDimitry Andric using _CheckArgsDep _LIBCPP_NODEBUG = typename conditional< 166fe6060f1SDimitry Andric _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type; 167fe6060f1SDimitry Andric 168349cc55cSDimitry Andric template<bool _Dummy = true, typename enable_if< 169fe6060f1SDimitry Andric _CheckArgsDep<_Dummy>::__enable_explicit_default() 170349cc55cSDimitry Andric >::type* = nullptr> 17106c3fb27SDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 172fe6060f1SDimitry Andric pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value && 173fe6060f1SDimitry Andric is_nothrow_default_constructible<second_type>::value) 174fe6060f1SDimitry Andric : first(), second() {} 175fe6060f1SDimitry Andric 176349cc55cSDimitry Andric template<bool _Dummy = true, typename enable_if< 177fe6060f1SDimitry Andric _CheckArgsDep<_Dummy>::__enable_implicit_default() 178349cc55cSDimitry Andric >::type* = nullptr> 17906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 180fe6060f1SDimitry Andric pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value && 181fe6060f1SDimitry Andric is_nothrow_default_constructible<second_type>::value) 182fe6060f1SDimitry Andric : first(), second() {} 183fe6060f1SDimitry Andric 184349cc55cSDimitry Andric template <bool _Dummy = true, typename enable_if< 185fe6060f1SDimitry Andric _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>() 186349cc55cSDimitry Andric >::type* = nullptr> 18706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 188fe6060f1SDimitry Andric explicit pair(_T1 const& __t1, _T2 const& __t2) 189fe6060f1SDimitry Andric _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && 190fe6060f1SDimitry Andric is_nothrow_copy_constructible<second_type>::value) 191fe6060f1SDimitry Andric : first(__t1), second(__t2) {} 192fe6060f1SDimitry Andric 193349cc55cSDimitry Andric template<bool _Dummy = true, typename enable_if< 194fe6060f1SDimitry Andric _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>() 195349cc55cSDimitry Andric >::type* = nullptr> 19606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 197fe6060f1SDimitry Andric pair(_T1 const& __t1, _T2 const& __t2) 198fe6060f1SDimitry Andric _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && 199fe6060f1SDimitry Andric is_nothrow_copy_constructible<second_type>::value) 200fe6060f1SDimitry Andric : first(__t1), second(__t2) {} 201fe6060f1SDimitry Andric 202349cc55cSDimitry Andric template < 20306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951 204349cc55cSDimitry Andric class _U1 = _T1, class _U2 = _T2, 205349cc55cSDimitry Andric #else 206349cc55cSDimitry Andric class _U1, class _U2, 207349cc55cSDimitry Andric #endif 208349cc55cSDimitry Andric typename enable_if<_CheckArgs::template __enable_explicit<_U1, _U2>()>::type* = nullptr 209349cc55cSDimitry Andric > 21006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 211fe6060f1SDimitry Andric explicit pair(_U1&& __u1, _U2&& __u2) 212fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && 213fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2>::value)) 21406c3fb27SDimitry Andric : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {} 215fe6060f1SDimitry Andric 216349cc55cSDimitry Andric template < 21706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951 218349cc55cSDimitry Andric class _U1 = _T1, class _U2 = _T2, 219349cc55cSDimitry Andric #else 220349cc55cSDimitry Andric class _U1, class _U2, 221349cc55cSDimitry Andric #endif 222349cc55cSDimitry Andric typename enable_if<_CheckArgs::template __enable_implicit<_U1, _U2>()>::type* = nullptr 223349cc55cSDimitry Andric > 22406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 225fe6060f1SDimitry Andric pair(_U1&& __u1, _U2&& __u2) 226fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && 227fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2>::value)) 22806c3fb27SDimitry Andric : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {} 229fe6060f1SDimitry Andric 23006c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 231bdd1243dSDimitry Andric template<class _U1, class _U2, __enable_if_t< 232bdd1243dSDimitry Andric _CheckArgs::template __is_pair_constructible<_U1&, _U2&>() 233bdd1243dSDimitry Andric >* = nullptr> 234bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 235bdd1243dSDimitry Andric explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>()) pair(pair<_U1, _U2>& __p) 236bdd1243dSDimitry Andric noexcept((is_nothrow_constructible<first_type, _U1&>::value && 237bdd1243dSDimitry Andric is_nothrow_constructible<second_type, _U2&>::value)) 238bdd1243dSDimitry Andric : first(__p.first), second(__p.second) {} 239bdd1243dSDimitry Andric #endif 240bdd1243dSDimitry Andric 241349cc55cSDimitry Andric template<class _U1, class _U2, typename enable_if< 242fe6060f1SDimitry Andric _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>() 243349cc55cSDimitry Andric >::type* = nullptr> 24406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 245fe6060f1SDimitry Andric explicit pair(pair<_U1, _U2> const& __p) 246fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && 247fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2 const&>::value)) 248fe6060f1SDimitry Andric : first(__p.first), second(__p.second) {} 249fe6060f1SDimitry Andric 250349cc55cSDimitry Andric template<class _U1, class _U2, typename enable_if< 251fe6060f1SDimitry Andric _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>() 252349cc55cSDimitry Andric >::type* = nullptr> 25306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 254fe6060f1SDimitry Andric pair(pair<_U1, _U2> const& __p) 255fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && 256fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2 const&>::value)) 257fe6060f1SDimitry Andric : first(__p.first), second(__p.second) {} 258fe6060f1SDimitry Andric 259349cc55cSDimitry Andric template<class _U1, class _U2, typename enable_if< 260fe6060f1SDimitry Andric _CheckArgs::template __enable_explicit<_U1, _U2>() 261349cc55cSDimitry Andric >::type* = nullptr> 26206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 263fe6060f1SDimitry Andric explicit pair(pair<_U1, _U2>&&__p) 264fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && 265fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2&&>::value)) 26606c3fb27SDimitry Andric : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} 267fe6060f1SDimitry Andric 268349cc55cSDimitry Andric template<class _U1, class _U2, typename enable_if< 269fe6060f1SDimitry Andric _CheckArgs::template __enable_implicit<_U1, _U2>() 270349cc55cSDimitry Andric >::type* = nullptr> 27106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 272fe6060f1SDimitry Andric pair(pair<_U1, _U2>&& __p) 273fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && 274fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2&&>::value)) 27506c3fb27SDimitry Andric : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} 276fe6060f1SDimitry Andric 27706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 278bdd1243dSDimitry Andric template<class _U1, class _U2, __enable_if_t< 279bdd1243dSDimitry Andric _CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>() 280bdd1243dSDimitry Andric >* = nullptr> 281bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 282bdd1243dSDimitry Andric explicit(!_CheckArgs::template __is_implicit<const _U1&&, const _U2&&>()) 283bdd1243dSDimitry Andric pair(const pair<_U1, _U2>&& __p) 284bdd1243dSDimitry Andric noexcept(is_nothrow_constructible<first_type, const _U1&&>::value && 285bdd1243dSDimitry Andric is_nothrow_constructible<second_type, const _U2&&>::value) 286bdd1243dSDimitry Andric : first(std::move(__p.first)), second(std::move(__p.second)) {} 287bdd1243dSDimitry Andric #endif 288bdd1243dSDimitry Andric 28906c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 29006c3fb27SDimitry Andric // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed. 291*3bd749dbSDimitry Andric template <class _PairLike> 29206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() { 293*3bd749dbSDimitry Andric if constexpr (__pair_like<_PairLike>) { 29406c3fb27SDimitry Andric return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> || 29506c3fb27SDimitry Andric !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>; 29606c3fb27SDimitry Andric } 29706c3fb27SDimitry Andric return false; 29806c3fb27SDimitry Andric } 299fe6060f1SDimitry Andric 30006c3fb27SDimitry Andric template <__pair_like _PairLike> 30106c3fb27SDimitry Andric requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike&&>()))> && 30206c3fb27SDimitry Andric is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike&&>()))>) 30306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>()) 30406c3fb27SDimitry Andric pair(_PairLike&& __p) 30506c3fb27SDimitry Andric : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {} 30606c3fb27SDimitry Andric # endif 307fe6060f1SDimitry Andric 308fe6060f1SDimitry Andric template <class... _Args1, class... _Args2> 30906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 310fe6060f1SDimitry Andric pair(piecewise_construct_t __pc, 311fe6060f1SDimitry Andric tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) 312fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value && 313fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _Args2...>::value)) 314fe6060f1SDimitry Andric : pair(__pc, __first_args, __second_args, 315fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Args1)>::type(), 316fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Args2) >::type()) {} 317fe6060f1SDimitry Andric 31806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 319bdd1243dSDimitry Andric pair& operator=(__conditional_t< 320fe6060f1SDimitry Andric is_copy_assignable<first_type>::value && 321fe6060f1SDimitry Andric is_copy_assignable<second_type>::value, 322bdd1243dSDimitry Andric pair, __nat> const& __p) 323fe6060f1SDimitry Andric _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value && 324fe6060f1SDimitry Andric is_nothrow_copy_assignable<second_type>::value) 325fe6060f1SDimitry Andric { 326fe6060f1SDimitry Andric first = __p.first; 327fe6060f1SDimitry Andric second = __p.second; 328fe6060f1SDimitry Andric return *this; 329fe6060f1SDimitry Andric } 330fe6060f1SDimitry Andric 33106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 332bdd1243dSDimitry Andric pair& operator=(__conditional_t< 333fe6060f1SDimitry Andric is_move_assignable<first_type>::value && 334fe6060f1SDimitry Andric is_move_assignable<second_type>::value, 335bdd1243dSDimitry Andric pair, __nat>&& __p) 336fe6060f1SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value && 337fe6060f1SDimitry Andric is_nothrow_move_assignable<second_type>::value) 338fe6060f1SDimitry Andric { 33906c3fb27SDimitry Andric first = std::forward<first_type>(__p.first); 34006c3fb27SDimitry Andric second = std::forward<second_type>(__p.second); 341fe6060f1SDimitry Andric return *this; 342fe6060f1SDimitry Andric } 343fe6060f1SDimitry Andric 34406c3fb27SDimitry Andric template <class _U1, class _U2, __enable_if_t< 34506c3fb27SDimitry Andric is_assignable<first_type&, _U1 const&>::value && 34606c3fb27SDimitry Andric is_assignable<second_type&, _U2 const&>::value 34706c3fb27SDimitry Andric >* = nullptr> 34806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 34906c3fb27SDimitry Andric pair& operator=(pair<_U1, _U2> const& __p) { 35006c3fb27SDimitry Andric first = __p.first; 35106c3fb27SDimitry Andric second = __p.second; 35206c3fb27SDimitry Andric return *this; 35306c3fb27SDimitry Andric } 35406c3fb27SDimitry Andric 35506c3fb27SDimitry Andric template <class _U1, class _U2, __enable_if_t< 35606c3fb27SDimitry Andric is_assignable<first_type&, _U1>::value && 35706c3fb27SDimitry Andric is_assignable<second_type&, _U2>::value 35806c3fb27SDimitry Andric >* = nullptr> 35906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 36006c3fb27SDimitry Andric pair& operator=(pair<_U1, _U2>&& __p) { 36106c3fb27SDimitry Andric first = std::forward<_U1>(__p.first); 36206c3fb27SDimitry Andric second = std::forward<_U2>(__p.second); 36306c3fb27SDimitry Andric return *this; 36406c3fb27SDimitry Andric } 36506c3fb27SDimitry Andric 36606c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 367bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 368bdd1243dSDimitry Andric const pair& operator=(pair const& __p) const 369bdd1243dSDimitry Andric noexcept(is_nothrow_copy_assignable_v<const first_type> && 370bdd1243dSDimitry Andric is_nothrow_copy_assignable_v<const second_type>) 371bdd1243dSDimitry Andric requires(is_copy_assignable_v<const first_type> && 372bdd1243dSDimitry Andric is_copy_assignable_v<const second_type>) { 373bdd1243dSDimitry Andric first = __p.first; 374bdd1243dSDimitry Andric second = __p.second; 375bdd1243dSDimitry Andric return *this; 376bdd1243dSDimitry Andric } 377bdd1243dSDimitry Andric 378bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 379bdd1243dSDimitry Andric const pair& operator=(pair&& __p) const 380bdd1243dSDimitry Andric noexcept(is_nothrow_assignable_v<const first_type&, first_type> && 381bdd1243dSDimitry Andric is_nothrow_assignable_v<const second_type&, second_type>) 382bdd1243dSDimitry Andric requires(is_assignable_v<const first_type&, first_type> && 383bdd1243dSDimitry Andric is_assignable_v<const second_type&, second_type>) { 384bdd1243dSDimitry Andric first = std::forward<first_type>(__p.first); 385bdd1243dSDimitry Andric second = std::forward<second_type>(__p.second); 386bdd1243dSDimitry Andric return *this; 387bdd1243dSDimitry Andric } 388bdd1243dSDimitry Andric 389bdd1243dSDimitry Andric template<class _U1, class _U2> 390bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 391bdd1243dSDimitry Andric const pair& operator=(const pair<_U1, _U2>& __p) const 392bdd1243dSDimitry Andric requires(is_assignable_v<const first_type&, const _U1&> && 393bdd1243dSDimitry Andric is_assignable_v<const second_type&, const _U2&>) { 394bdd1243dSDimitry Andric first = __p.first; 395bdd1243dSDimitry Andric second = __p.second; 396bdd1243dSDimitry Andric return *this; 397bdd1243dSDimitry Andric } 398bdd1243dSDimitry Andric 399bdd1243dSDimitry Andric template<class _U1, class _U2> 400bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 401bdd1243dSDimitry Andric const pair& operator=(pair<_U1, _U2>&& __p) const 402bdd1243dSDimitry Andric requires(is_assignable_v<const first_type&, _U1> && 403bdd1243dSDimitry Andric is_assignable_v<const second_type&, _U2>) { 404bdd1243dSDimitry Andric first = std::forward<_U1>(__p.first); 405bdd1243dSDimitry Andric second = std::forward<_U2>(__p.second); 406bdd1243dSDimitry Andric return *this; 407bdd1243dSDimitry Andric } 408bdd1243dSDimitry Andric 40906c3fb27SDimitry Andric template <__pair_like _PairLike> 41006c3fb27SDimitry Andric requires(__different_from<_PairLike, pair> && 41106c3fb27SDimitry Andric !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && 41206c3fb27SDimitry Andric is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> && 41306c3fb27SDimitry Andric is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>) 41406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) { 41506c3fb27SDimitry Andric first = std::get<0>(std::forward<_PairLike>(__p)); 41606c3fb27SDimitry Andric second = std::get<1>(std::forward<_PairLike>(__p)); 417fe6060f1SDimitry Andric return *this; 418fe6060f1SDimitry Andric } 419fe6060f1SDimitry Andric 42006c3fb27SDimitry Andric template <__pair_like _PairLike> 42106c3fb27SDimitry Andric requires(__different_from<_PairLike, pair> && 42206c3fb27SDimitry Andric !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && 42306c3fb27SDimitry Andric is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> && 42406c3fb27SDimitry Andric is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>) 42506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const { 42606c3fb27SDimitry Andric first = std::get<0>(std::forward<_PairLike>(__p)); 42706c3fb27SDimitry Andric second = std::get<1>(std::forward<_PairLike>(__p)); 42806c3fb27SDimitry Andric return *this; 42906c3fb27SDimitry Andric } 43006c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER >= 23 43106c3fb27SDimitry Andric 43206c3fb27SDimitry Andric // Prior to C++23, we provide an approximation of constructors and assignment operators from 43306c3fb27SDimitry Andric // pair-like types. This was historically provided as an extension. 43406c3fb27SDimitry Andric #if _LIBCPP_STD_VER < 23 43506c3fb27SDimitry Andric // from std::tuple 43606c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 43706c3fb27SDimitry Andric is_convertible<_U1 const&, _T1>::value && 43806c3fb27SDimitry Andric is_convertible<_U2 const&, _T2>::value 43906c3fb27SDimitry Andric >* = nullptr> 44006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 44106c3fb27SDimitry Andric pair(tuple<_U1, _U2> const& __p) 44206c3fb27SDimitry Andric : first(std::get<0>(__p)), 44306c3fb27SDimitry Andric second(std::get<1>(__p)) {} 44406c3fb27SDimitry Andric 44506c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 44606c3fb27SDimitry Andric is_constructible<_T1, _U1 const&>::value && 44706c3fb27SDimitry Andric is_constructible<_T2, _U2 const&>::value && 44806c3fb27SDimitry Andric !(is_convertible<_U1 const&, _T1>::value && 44906c3fb27SDimitry Andric is_convertible<_U2 const&, _T2>::value) 45006c3fb27SDimitry Andric >* = nullptr> 45106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 45206c3fb27SDimitry Andric explicit 45306c3fb27SDimitry Andric pair(tuple<_U1, _U2> const& __p) 45406c3fb27SDimitry Andric : first(std::get<0>(__p)), 45506c3fb27SDimitry Andric second(std::get<1>(__p)) {} 45606c3fb27SDimitry Andric 45706c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 45806c3fb27SDimitry Andric is_convertible<_U1, _T1>::value && 45906c3fb27SDimitry Andric is_convertible<_U2, _T2>::value 46006c3fb27SDimitry Andric >* = nullptr> 46106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 46206c3fb27SDimitry Andric pair(tuple<_U1, _U2>&& __p) 46306c3fb27SDimitry Andric : first(std::get<0>(std::move(__p))), 46406c3fb27SDimitry Andric second(std::get<1>(std::move(__p))) {} 46506c3fb27SDimitry Andric 46606c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 46706c3fb27SDimitry Andric is_constructible<_T1, _U1>::value && 46806c3fb27SDimitry Andric is_constructible<_T2, _U2>::value && 46906c3fb27SDimitry Andric !(is_convertible<_U1, _T1>::value && 47006c3fb27SDimitry Andric is_convertible<_U2, _T2>::value) 47106c3fb27SDimitry Andric >* = nullptr> 47206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 47306c3fb27SDimitry Andric explicit 47406c3fb27SDimitry Andric pair(tuple<_U1, _U2>&& __p) 47506c3fb27SDimitry Andric : first(std::get<0>(std::move(__p))), 47606c3fb27SDimitry Andric second(std::get<1>(std::move(__p))) {} 47706c3fb27SDimitry Andric 47806c3fb27SDimitry Andric 47906c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 48006c3fb27SDimitry Andric is_assignable<_T1&, _U1 const&>::value && 48106c3fb27SDimitry Andric is_assignable<_T2&, _U2 const&>::value 48206c3fb27SDimitry Andric >* = nullptr> 48306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 48406c3fb27SDimitry Andric pair& operator=(tuple<_U1, _U2> const& __p) { 48506c3fb27SDimitry Andric first = std::get<0>(__p); 48606c3fb27SDimitry Andric second = std::get<1>(__p); 48706c3fb27SDimitry Andric return *this; 48806c3fb27SDimitry Andric } 48906c3fb27SDimitry Andric 49006c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 49106c3fb27SDimitry Andric is_assignable<_T1&, _U1&&>::value && 49206c3fb27SDimitry Andric is_assignable<_T2&, _U2&&>::value 49306c3fb27SDimitry Andric >* = nullptr> 49406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 49506c3fb27SDimitry Andric pair& operator=(tuple<_U1, _U2>&& __p) { 49606c3fb27SDimitry Andric first = std::get<0>(std::move(__p)); 49706c3fb27SDimitry Andric second = std::get<1>(std::move(__p)); 49806c3fb27SDimitry Andric return *this; 49906c3fb27SDimitry Andric } 50006c3fb27SDimitry Andric 50106c3fb27SDimitry Andric // from std::array 50206c3fb27SDimitry Andric template<class _Up, __enable_if_t< 50306c3fb27SDimitry Andric is_convertible<_Up const&, _T1>::value && 50406c3fb27SDimitry Andric is_convertible<_Up const&, _T2>::value 50506c3fb27SDimitry Andric >* = nullptr> 50606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 50706c3fb27SDimitry Andric pair(array<_Up, 2> const& __p) 50806c3fb27SDimitry Andric : first(__p[0]), 50906c3fb27SDimitry Andric second(__p[1]) {} 51006c3fb27SDimitry Andric 51106c3fb27SDimitry Andric template<class _Up, __enable_if_t< 51206c3fb27SDimitry Andric is_constructible<_T1, _Up const&>::value && 51306c3fb27SDimitry Andric is_constructible<_T2, _Up const&>::value && 51406c3fb27SDimitry Andric !(is_convertible<_Up const&, _T1>::value && 51506c3fb27SDimitry Andric is_convertible<_Up const&, _T2>::value) 51606c3fb27SDimitry Andric >* = nullptr> 51706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 51806c3fb27SDimitry Andric explicit 51906c3fb27SDimitry Andric pair(array<_Up, 2> const& __p) 52006c3fb27SDimitry Andric : first(__p[0]), 52106c3fb27SDimitry Andric second(__p[1]) {} 52206c3fb27SDimitry Andric 52306c3fb27SDimitry Andric template<class _Up, __enable_if_t< 52406c3fb27SDimitry Andric is_convertible<_Up, _T1>::value && 52506c3fb27SDimitry Andric is_convertible<_Up, _T2>::value 52606c3fb27SDimitry Andric >* = nullptr> 52706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 52806c3fb27SDimitry Andric pair(array<_Up, 2>&& __p) 52906c3fb27SDimitry Andric : first(std::move(__p)[0]), 53006c3fb27SDimitry Andric second(std::move(__p)[1]) {} 53106c3fb27SDimitry Andric 53206c3fb27SDimitry Andric template<class _Up, __enable_if_t< 53306c3fb27SDimitry Andric is_constructible<_T1, _Up>::value && 53406c3fb27SDimitry Andric is_constructible<_T2, _Up>::value && 53506c3fb27SDimitry Andric !(is_convertible<_Up, _T1>::value && 53606c3fb27SDimitry Andric is_convertible<_Up, _T2>::value) 53706c3fb27SDimitry Andric >* = nullptr> 53806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 53906c3fb27SDimitry Andric explicit 54006c3fb27SDimitry Andric pair(array<_Up, 2>&& __p) 54106c3fb27SDimitry Andric : first(std::move(__p)[0]), 54206c3fb27SDimitry Andric second(std::move(__p)[1]) {} 54306c3fb27SDimitry Andric 54406c3fb27SDimitry Andric 54506c3fb27SDimitry Andric template<class _Up, __enable_if_t< 54606c3fb27SDimitry Andric is_assignable<_T1&, _Up const&>::value && 54706c3fb27SDimitry Andric is_assignable<_T2&, _Up const&>::value 54806c3fb27SDimitry Andric >* = nullptr> 54906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 55006c3fb27SDimitry Andric pair& operator=(array<_Up, 2> const& __p) { 55106c3fb27SDimitry Andric first = std::get<0>(__p); 55206c3fb27SDimitry Andric second = std::get<1>(__p); 55306c3fb27SDimitry Andric return *this; 55406c3fb27SDimitry Andric } 55506c3fb27SDimitry Andric 55606c3fb27SDimitry Andric template<class _Up, __enable_if_t< 55706c3fb27SDimitry Andric is_assignable<_T1&, _Up>::value && 55806c3fb27SDimitry Andric is_assignable<_T2&, _Up>::value 55906c3fb27SDimitry Andric >* = nullptr> 56006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 56106c3fb27SDimitry Andric pair& operator=(array<_Up, 2>&& __p) { 56206c3fb27SDimitry Andric first = std::get<0>(std::move(__p)); 56306c3fb27SDimitry Andric second = std::get<1>(std::move(__p)); 56406c3fb27SDimitry Andric return *this; 56506c3fb27SDimitry Andric } 56606c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER < 23 56706c3fb27SDimitry Andric #endif // _LIBCPP_CXX03_LANG 56806c3fb27SDimitry Andric 56906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 570fe6060f1SDimitry Andric void 571fe6060f1SDimitry Andric swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value && 572fe6060f1SDimitry Andric __is_nothrow_swappable<second_type>::value) 573fe6060f1SDimitry Andric { 57406c3fb27SDimitry Andric using std::swap; 575fe6060f1SDimitry Andric swap(first, __p.first); 576fe6060f1SDimitry Andric swap(second, __p.second); 577fe6060f1SDimitry Andric } 578bdd1243dSDimitry Andric 57906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 580bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 581bdd1243dSDimitry Andric void swap(const pair& __p) const 582bdd1243dSDimitry Andric noexcept(__is_nothrow_swappable<const first_type>::value && 583bdd1243dSDimitry Andric __is_nothrow_swappable<const second_type>::value) 584bdd1243dSDimitry Andric { 585bdd1243dSDimitry Andric using std::swap; 586bdd1243dSDimitry Andric swap(first, __p.first); 587bdd1243dSDimitry Andric swap(second, __p.second); 588bdd1243dSDimitry Andric } 589bdd1243dSDimitry Andric #endif 590fe6060f1SDimitry Andric private: 591fe6060f1SDimitry Andric 592fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 593fe6060f1SDimitry Andric template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> 59406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 595fe6060f1SDimitry Andric pair(piecewise_construct_t, 596fe6060f1SDimitry Andric tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, 597fe6060f1SDimitry Andric __tuple_indices<_I1...>, __tuple_indices<_I2...>); 598fe6060f1SDimitry Andric #endif 599fe6060f1SDimitry Andric }; 600fe6060f1SDimitry Andric 60106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 17 602fe6060f1SDimitry Andric template<class _T1, class _T2> 603fe6060f1SDimitry Andric pair(_T1, _T2) -> pair<_T1, _T2>; 604349cc55cSDimitry Andric #endif 605349cc55cSDimitry Andric 606349cc55cSDimitry Andric // [pairs.spec], specialized algorithms 607fe6060f1SDimitry Andric 60806c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 60906c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 610fe6060f1SDimitry Andric bool 61106c3fb27SDimitry Andric operator==(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 612fe6060f1SDimitry Andric { 613fe6060f1SDimitry Andric return __x.first == __y.first && __x.second == __y.second; 614fe6060f1SDimitry Andric } 615fe6060f1SDimitry Andric 61606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 617349cc55cSDimitry Andric 61806c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 619349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 620349cc55cSDimitry Andric common_comparison_category_t< 62106c3fb27SDimitry Andric __synth_three_way_result<_T1, _U1>, 62206c3fb27SDimitry Andric __synth_three_way_result<_T2, _U2> > 62306c3fb27SDimitry Andric operator<=>(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 624349cc55cSDimitry Andric { 62506c3fb27SDimitry Andric if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) { 626349cc55cSDimitry Andric return __c; 627349cc55cSDimitry Andric } 62806c3fb27SDimitry Andric return std::__synth_three_way(__x.second, __y.second); 629349cc55cSDimitry Andric } 630349cc55cSDimitry Andric 63106c3fb27SDimitry Andric #else // _LIBCPP_STD_VER >= 20 632349cc55cSDimitry Andric 63306c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 63406c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 635fe6060f1SDimitry Andric bool 63606c3fb27SDimitry Andric operator!=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 637fe6060f1SDimitry Andric { 638fe6060f1SDimitry Andric return !(__x == __y); 639fe6060f1SDimitry Andric } 640fe6060f1SDimitry Andric 64106c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 64206c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 643fe6060f1SDimitry Andric bool 64406c3fb27SDimitry Andric operator< (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 645fe6060f1SDimitry Andric { 646fe6060f1SDimitry Andric return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second); 647fe6060f1SDimitry Andric } 648fe6060f1SDimitry Andric 64906c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 65006c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 651fe6060f1SDimitry Andric bool 65206c3fb27SDimitry Andric operator> (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 653fe6060f1SDimitry Andric { 654fe6060f1SDimitry Andric return __y < __x; 655fe6060f1SDimitry Andric } 656fe6060f1SDimitry Andric 65706c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 65806c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 659fe6060f1SDimitry Andric bool 66006c3fb27SDimitry Andric operator>=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 661fe6060f1SDimitry Andric { 662fe6060f1SDimitry Andric return !(__x < __y); 663fe6060f1SDimitry Andric } 664fe6060f1SDimitry Andric 66506c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 66606c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 667fe6060f1SDimitry Andric bool 66806c3fb27SDimitry Andric operator<=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 669fe6060f1SDimitry Andric { 670fe6060f1SDimitry Andric return !(__y < __x); 671fe6060f1SDimitry Andric } 672fe6060f1SDimitry Andric 67306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 67481ad6265SDimitry Andric 67506c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 67681ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2, template<class> class _TQual, template<class> class _UQual> 67781ad6265SDimitry Andric requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, 67881ad6265SDimitry Andric common_reference_t<_TQual<_T2>, _UQual<_U2>>>; } 67981ad6265SDimitry Andric struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> { 68081ad6265SDimitry Andric using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, 68181ad6265SDimitry Andric common_reference_t<_TQual<_T2>, _UQual<_U2>>>; 68281ad6265SDimitry Andric }; 68381ad6265SDimitry Andric 68481ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 68581ad6265SDimitry Andric requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; } 68681ad6265SDimitry Andric struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> { 68781ad6265SDimitry Andric using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; 68881ad6265SDimitry Andric }; 68906c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 23 690349cc55cSDimitry Andric 691fe6060f1SDimitry Andric template <class _T1, class _T2> 69206c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 693fe6060f1SDimitry Andric typename enable_if 694fe6060f1SDimitry Andric < 695fe6060f1SDimitry Andric __is_swappable<_T1>::value && 696fe6060f1SDimitry Andric __is_swappable<_T2>::value, 697fe6060f1SDimitry Andric void 698fe6060f1SDimitry Andric >::type 699fe6060f1SDimitry Andric swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) 700fe6060f1SDimitry Andric _NOEXCEPT_((__is_nothrow_swappable<_T1>::value && 701fe6060f1SDimitry Andric __is_nothrow_swappable<_T2>::value)) 702fe6060f1SDimitry Andric { 703fe6060f1SDimitry Andric __x.swap(__y); 704fe6060f1SDimitry Andric } 705fe6060f1SDimitry Andric 70606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 707bdd1243dSDimitry Andric template <class _T1, class _T2> 708bdd1243dSDimitry Andric requires (__is_swappable<const _T1>::value && 709bdd1243dSDimitry Andric __is_swappable<const _T2>::value) 710bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 711bdd1243dSDimitry Andric void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 712bdd1243dSDimitry Andric noexcept(noexcept(__x.swap(__y))) 713bdd1243dSDimitry Andric { 714bdd1243dSDimitry Andric __x.swap(__y); 715bdd1243dSDimitry Andric } 716bdd1243dSDimitry Andric #endif 717fe6060f1SDimitry Andric 718fe6060f1SDimitry Andric template <class _T1, class _T2> 71906c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 720fe6060f1SDimitry Andric pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> 721fe6060f1SDimitry Andric make_pair(_T1&& __t1, _T2&& __t2) 722fe6060f1SDimitry Andric { 723fe6060f1SDimitry Andric return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> 72406c3fb27SDimitry Andric (std::forward<_T1>(__t1), std::forward<_T2>(__t2)); 725fe6060f1SDimitry Andric } 726fe6060f1SDimitry Andric 727fe6060f1SDimitry Andric template <class _T1, class _T2> 728fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > 729fe6060f1SDimitry Andric : public integral_constant<size_t, 2> {}; 730fe6060f1SDimitry Andric 731fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 732fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> > 733fe6060f1SDimitry Andric { 734fe6060f1SDimitry Andric static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>"); 735fe6060f1SDimitry Andric }; 736fe6060f1SDimitry Andric 737fe6060f1SDimitry Andric template <class _T1, class _T2> 738fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > 739fe6060f1SDimitry Andric { 74006c3fb27SDimitry Andric using type _LIBCPP_NODEBUG = _T1; 741fe6060f1SDimitry Andric }; 742fe6060f1SDimitry Andric 743fe6060f1SDimitry Andric template <class _T1, class _T2> 744fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > 745fe6060f1SDimitry Andric { 74606c3fb27SDimitry Andric using type _LIBCPP_NODEBUG = _T2; 747fe6060f1SDimitry Andric }; 748fe6060f1SDimitry Andric 749fe6060f1SDimitry Andric template <size_t _Ip> struct __get_pair; 750fe6060f1SDimitry Andric 751fe6060f1SDimitry Andric template <> 752fe6060f1SDimitry Andric struct __get_pair<0> 753fe6060f1SDimitry Andric { 754fe6060f1SDimitry Andric template <class _T1, class _T2> 755fe6060f1SDimitry Andric static 75606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 757fe6060f1SDimitry Andric _T1& 758fe6060f1SDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} 759fe6060f1SDimitry Andric 760fe6060f1SDimitry Andric template <class _T1, class _T2> 761fe6060f1SDimitry Andric static 76206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 763fe6060f1SDimitry Andric const _T1& 764fe6060f1SDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} 765fe6060f1SDimitry Andric 766fe6060f1SDimitry Andric template <class _T1, class _T2> 767fe6060f1SDimitry Andric static 76806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 769fe6060f1SDimitry Andric _T1&& 77006c3fb27SDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T1>(__p.first);} 771fe6060f1SDimitry Andric 772fe6060f1SDimitry Andric template <class _T1, class _T2> 773fe6060f1SDimitry Andric static 77406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 775fe6060f1SDimitry Andric const _T1&& 77606c3fb27SDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T1>(__p.first);} 777fe6060f1SDimitry Andric }; 778fe6060f1SDimitry Andric 779fe6060f1SDimitry Andric template <> 780fe6060f1SDimitry Andric struct __get_pair<1> 781fe6060f1SDimitry Andric { 782fe6060f1SDimitry Andric template <class _T1, class _T2> 783fe6060f1SDimitry Andric static 78406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 785fe6060f1SDimitry Andric _T2& 786fe6060f1SDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} 787fe6060f1SDimitry Andric 788fe6060f1SDimitry Andric template <class _T1, class _T2> 789fe6060f1SDimitry Andric static 79006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 791fe6060f1SDimitry Andric const _T2& 792fe6060f1SDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} 793fe6060f1SDimitry Andric 794fe6060f1SDimitry Andric template <class _T1, class _T2> 795fe6060f1SDimitry Andric static 79606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 797fe6060f1SDimitry Andric _T2&& 79806c3fb27SDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T2>(__p.second);} 799fe6060f1SDimitry Andric 800fe6060f1SDimitry Andric template <class _T1, class _T2> 801fe6060f1SDimitry Andric static 80206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 803fe6060f1SDimitry Andric const _T2&& 80406c3fb27SDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T2>(__p.second);} 805fe6060f1SDimitry Andric }; 806fe6060f1SDimitry Andric 807fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 80806c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 809fe6060f1SDimitry Andric typename tuple_element<_Ip, pair<_T1, _T2> >::type& 810fe6060f1SDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT 811fe6060f1SDimitry Andric { 812fe6060f1SDimitry Andric return __get_pair<_Ip>::get(__p); 813fe6060f1SDimitry Andric } 814fe6060f1SDimitry Andric 815fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 81606c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 817fe6060f1SDimitry Andric const typename tuple_element<_Ip, pair<_T1, _T2> >::type& 818fe6060f1SDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT 819fe6060f1SDimitry Andric { 820fe6060f1SDimitry Andric return __get_pair<_Ip>::get(__p); 821fe6060f1SDimitry Andric } 822fe6060f1SDimitry Andric 823fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 82406c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 825fe6060f1SDimitry Andric typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 826fe6060f1SDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT 827fe6060f1SDimitry Andric { 82806c3fb27SDimitry Andric return __get_pair<_Ip>::get(std::move(__p)); 829fe6060f1SDimitry Andric } 830fe6060f1SDimitry Andric 831fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 83206c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 833fe6060f1SDimitry Andric const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 834fe6060f1SDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT 835fe6060f1SDimitry Andric { 83606c3fb27SDimitry Andric return __get_pair<_Ip>::get(std::move(__p)); 837fe6060f1SDimitry Andric } 838fe6060f1SDimitry Andric 83906c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 840fe6060f1SDimitry Andric template <class _T1, class _T2> 84106c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 842fe6060f1SDimitry Andric constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT 843fe6060f1SDimitry Andric { 844fe6060f1SDimitry Andric return __get_pair<0>::get(__p); 845fe6060f1SDimitry Andric } 846fe6060f1SDimitry Andric 847fe6060f1SDimitry Andric template <class _T1, class _T2> 84806c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 849fe6060f1SDimitry Andric constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT 850fe6060f1SDimitry Andric { 851fe6060f1SDimitry Andric return __get_pair<0>::get(__p); 852fe6060f1SDimitry Andric } 853fe6060f1SDimitry Andric 854fe6060f1SDimitry Andric template <class _T1, class _T2> 85506c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 856fe6060f1SDimitry Andric constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT 857fe6060f1SDimitry Andric { 85806c3fb27SDimitry Andric return __get_pair<0>::get(std::move(__p)); 859fe6060f1SDimitry Andric } 860fe6060f1SDimitry Andric 861fe6060f1SDimitry Andric template <class _T1, class _T2> 86206c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 863fe6060f1SDimitry Andric constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT 864fe6060f1SDimitry Andric { 86506c3fb27SDimitry Andric return __get_pair<0>::get(std::move(__p)); 866fe6060f1SDimitry Andric } 867fe6060f1SDimitry Andric 868fe6060f1SDimitry Andric template <class _T1, class _T2> 86906c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 870fe6060f1SDimitry Andric constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT 871fe6060f1SDimitry Andric { 872fe6060f1SDimitry Andric return __get_pair<1>::get(__p); 873fe6060f1SDimitry Andric } 874fe6060f1SDimitry Andric 875fe6060f1SDimitry Andric template <class _T1, class _T2> 87606c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 877fe6060f1SDimitry Andric constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT 878fe6060f1SDimitry Andric { 879fe6060f1SDimitry Andric return __get_pair<1>::get(__p); 880fe6060f1SDimitry Andric } 881fe6060f1SDimitry Andric 882fe6060f1SDimitry Andric template <class _T1, class _T2> 88306c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 884fe6060f1SDimitry Andric constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT 885fe6060f1SDimitry Andric { 88606c3fb27SDimitry Andric return __get_pair<1>::get(std::move(__p)); 887fe6060f1SDimitry Andric } 888fe6060f1SDimitry Andric 889fe6060f1SDimitry Andric template <class _T1, class _T2> 89006c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 891fe6060f1SDimitry Andric constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT 892fe6060f1SDimitry Andric { 89306c3fb27SDimitry Andric return __get_pair<1>::get(std::move(__p)); 894fe6060f1SDimitry Andric } 895fe6060f1SDimitry Andric 89606c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 14 897fe6060f1SDimitry Andric 898fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 899fe6060f1SDimitry Andric 90006c3fb27SDimitry Andric _LIBCPP_POP_MACROS 90106c3fb27SDimitry Andric 902fe6060f1SDimitry Andric #endif // _LIBCPP___UTILITY_PAIR_H 903