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> 14*06c3fb27SDimitry Andric #include <__concepts/different_from.h> 15fe6060f1SDimitry Andric #include <__config> 16*06c3fb27SDimitry Andric #include <__fwd/array.h> 17bdd1243dSDimitry Andric #include <__fwd/get.h> 18*06c3fb27SDimitry Andric #include <__fwd/pair.h> 19*06c3fb27SDimitry Andric #include <__fwd/subrange.h> 20bdd1243dSDimitry Andric #include <__fwd/tuple.h> 21*06c3fb27SDimitry Andric #include <__tuple/pair_like.h> 22*06c3fb27SDimitry Andric #include <__tuple/sfinae_helpers.h> 23*06c3fb27SDimitry Andric #include <__tuple/tuple_element.h> 24*06c3fb27SDimitry Andric #include <__tuple/tuple_indices.h> 25*06c3fb27SDimitry 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> 29*06c3fb27SDimitry Andric #include <__type_traits/decay.h> 30*06c3fb27SDimitry 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> 47*06c3fb27SDimitry Andric #include <__type_traits/remove_cvref.h> 48*06c3fb27SDimitry Andric #include <__type_traits/unwrap_ref.h> 49*06c3fb27SDimitry 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 59*06c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS 60*06c3fb27SDimitry Andric #include <__undef_macros> 61*06c3fb27SDimitry Andric 62fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 63fe6060f1SDimitry Andric 64fe6060f1SDimitry Andric template <class, class> 65fe6060f1SDimitry Andric struct __non_trivially_copyable_base { 66*06c3fb27SDimitry Andric _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI 67fe6060f1SDimitry Andric __non_trivially_copyable_base() _NOEXCEPT {} 68*06c3fb27SDimitry Andric _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI 69fe6060f1SDimitry Andric __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {} 70fe6060f1SDimitry Andric }; 71*06c3fb27SDimitry Andric 72*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 73*06c3fb27SDimitry Andric template <class _Tp> 74*06c3fb27SDimitry Andric struct __is_specialization_of_subrange : false_type {}; 75*06c3fb27SDimitry Andric 76*06c3fb27SDimitry Andric template <class _Iter, class _Sent, ranges::subrange_kind _Kind> 77*06c3fb27SDimitry 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 { 86*06c3fb27SDimitry Andric using first_type = _T1; 87*06c3fb27SDimitry Andric using second_type = _T2; 88fe6060f1SDimitry Andric 89fe6060f1SDimitry Andric _T1 first; 90fe6060f1SDimitry Andric _T2 second; 91fe6060f1SDimitry Andric 92*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default; 93*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default; 94fe6060f1SDimitry Andric 95fe6060f1SDimitry Andric #ifdef _LIBCPP_CXX03_LANG 96*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 97fe6060f1SDimitry Andric pair() : first(), second() {} 98fe6060f1SDimitry Andric 99*06c3fb27SDimitry 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> 103*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 104fe6060f1SDimitry Andric pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} 105fe6060f1SDimitry Andric 106*06c3fb27SDimitry 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 } 112*06c3fb27SDimitry Andric 113*06c3fb27SDimitry Andric // Extension: This is provided in C++03 because it allows properly handling the 114*06c3fb27SDimitry Andric // assignment to a pair containing references, which would be a hard 115*06c3fb27SDimitry Andric // error otherwise. 116*06c3fb27SDimitry Andric template <class _U1, class _U2, class = __enable_if_t< 117*06c3fb27SDimitry Andric is_assignable<first_type&, _U1 const&>::value && 118*06c3fb27SDimitry Andric is_assignable<second_type&, _U2 const&>::value 119*06c3fb27SDimitry Andric > > 120*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI 121*06c3fb27SDimitry Andric pair& operator=(pair<_U1, _U2> const& __p) { 122*06c3fb27SDimitry Andric first = __p.first; 123*06c3fb27SDimitry Andric second = __p.second; 124*06c3fb27SDimitry Andric return *this; 125*06c3fb27SDimitry Andric } 126fe6060f1SDimitry Andric #else 127fe6060f1SDimitry Andric struct _CheckArgs { 128fe6060f1SDimitry Andric template <int&...> 129*06c3fb27SDimitry 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&...> 136*06c3fb27SDimitry 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> 142*06c3fb27SDimitry 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> 148*06c3fb27SDimitry 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> 154*06c3fb27SDimitry 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> 159*06c3fb27SDimitry 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> 171*06c3fb27SDimitry 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> 179*06c3fb27SDimitry 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> 187*06c3fb27SDimitry 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> 196*06c3fb27SDimitry 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 < 203*06c3fb27SDimitry 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 > 210*06c3fb27SDimitry 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)) 214*06c3fb27SDimitry Andric : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {} 215fe6060f1SDimitry Andric 216349cc55cSDimitry Andric template < 217*06c3fb27SDimitry 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 > 224*06c3fb27SDimitry 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)) 228*06c3fb27SDimitry Andric : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {} 229fe6060f1SDimitry Andric 230*06c3fb27SDimitry 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> 244*06c3fb27SDimitry 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> 253*06c3fb27SDimitry 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> 262*06c3fb27SDimitry 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)) 266*06c3fb27SDimitry 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> 271*06c3fb27SDimitry 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)) 275*06c3fb27SDimitry Andric : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} 276fe6060f1SDimitry Andric 277*06c3fb27SDimitry 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 289*06c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 290*06c3fb27SDimitry Andric // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed. 291*06c3fb27SDimitry Andric template <class _PairLike, bool _Enable = tuple_size<remove_cvref_t<_PairLike>>::value == 2> 292*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() { 293*06c3fb27SDimitry Andric if constexpr (tuple_size<remove_cvref_t<_PairLike>>::value == 2) { 294*06c3fb27SDimitry Andric return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> || 295*06c3fb27SDimitry Andric !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>; 296*06c3fb27SDimitry Andric } 297*06c3fb27SDimitry Andric return false; 298*06c3fb27SDimitry Andric } 299fe6060f1SDimitry Andric 300*06c3fb27SDimitry Andric template <__pair_like _PairLike> 301*06c3fb27SDimitry Andric requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike&&>()))> && 302*06c3fb27SDimitry Andric is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike&&>()))>) 303*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>()) 304*06c3fb27SDimitry Andric pair(_PairLike&& __p) 305*06c3fb27SDimitry Andric : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {} 306*06c3fb27SDimitry Andric # endif 307fe6060f1SDimitry Andric 308fe6060f1SDimitry Andric template <class... _Args1, class... _Args2> 309*06c3fb27SDimitry 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 318*06c3fb27SDimitry 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 331*06c3fb27SDimitry 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 { 339*06c3fb27SDimitry Andric first = std::forward<first_type>(__p.first); 340*06c3fb27SDimitry Andric second = std::forward<second_type>(__p.second); 341fe6060f1SDimitry Andric return *this; 342fe6060f1SDimitry Andric } 343fe6060f1SDimitry Andric 344*06c3fb27SDimitry Andric template <class _U1, class _U2, __enable_if_t< 345*06c3fb27SDimitry Andric is_assignable<first_type&, _U1 const&>::value && 346*06c3fb27SDimitry Andric is_assignable<second_type&, _U2 const&>::value 347*06c3fb27SDimitry Andric >* = nullptr> 348*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 349*06c3fb27SDimitry Andric pair& operator=(pair<_U1, _U2> const& __p) { 350*06c3fb27SDimitry Andric first = __p.first; 351*06c3fb27SDimitry Andric second = __p.second; 352*06c3fb27SDimitry Andric return *this; 353*06c3fb27SDimitry Andric } 354*06c3fb27SDimitry Andric 355*06c3fb27SDimitry Andric template <class _U1, class _U2, __enable_if_t< 356*06c3fb27SDimitry Andric is_assignable<first_type&, _U1>::value && 357*06c3fb27SDimitry Andric is_assignable<second_type&, _U2>::value 358*06c3fb27SDimitry Andric >* = nullptr> 359*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 360*06c3fb27SDimitry Andric pair& operator=(pair<_U1, _U2>&& __p) { 361*06c3fb27SDimitry Andric first = std::forward<_U1>(__p.first); 362*06c3fb27SDimitry Andric second = std::forward<_U2>(__p.second); 363*06c3fb27SDimitry Andric return *this; 364*06c3fb27SDimitry Andric } 365*06c3fb27SDimitry Andric 366*06c3fb27SDimitry 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 409*06c3fb27SDimitry Andric template <__pair_like _PairLike> 410*06c3fb27SDimitry Andric requires(__different_from<_PairLike, pair> && 411*06c3fb27SDimitry Andric !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && 412*06c3fb27SDimitry Andric is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> && 413*06c3fb27SDimitry Andric is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>) 414*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) { 415*06c3fb27SDimitry Andric first = std::get<0>(std::forward<_PairLike>(__p)); 416*06c3fb27SDimitry Andric second = std::get<1>(std::forward<_PairLike>(__p)); 417fe6060f1SDimitry Andric return *this; 418fe6060f1SDimitry Andric } 419fe6060f1SDimitry Andric 420*06c3fb27SDimitry Andric template <__pair_like _PairLike> 421*06c3fb27SDimitry Andric requires(__different_from<_PairLike, pair> && 422*06c3fb27SDimitry Andric !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && 423*06c3fb27SDimitry Andric is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> && 424*06c3fb27SDimitry Andric is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>) 425*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const { 426*06c3fb27SDimitry Andric first = std::get<0>(std::forward<_PairLike>(__p)); 427*06c3fb27SDimitry Andric second = std::get<1>(std::forward<_PairLike>(__p)); 428*06c3fb27SDimitry Andric return *this; 429*06c3fb27SDimitry Andric } 430*06c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER >= 23 431*06c3fb27SDimitry Andric 432*06c3fb27SDimitry Andric // Prior to C++23, we provide an approximation of constructors and assignment operators from 433*06c3fb27SDimitry Andric // pair-like types. This was historically provided as an extension. 434*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER < 23 435*06c3fb27SDimitry Andric // from std::tuple 436*06c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 437*06c3fb27SDimitry Andric is_convertible<_U1 const&, _T1>::value && 438*06c3fb27SDimitry Andric is_convertible<_U2 const&, _T2>::value 439*06c3fb27SDimitry Andric >* = nullptr> 440*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 441*06c3fb27SDimitry Andric pair(tuple<_U1, _U2> const& __p) 442*06c3fb27SDimitry Andric : first(std::get<0>(__p)), 443*06c3fb27SDimitry Andric second(std::get<1>(__p)) {} 444*06c3fb27SDimitry Andric 445*06c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 446*06c3fb27SDimitry Andric is_constructible<_T1, _U1 const&>::value && 447*06c3fb27SDimitry Andric is_constructible<_T2, _U2 const&>::value && 448*06c3fb27SDimitry Andric !(is_convertible<_U1 const&, _T1>::value && 449*06c3fb27SDimitry Andric is_convertible<_U2 const&, _T2>::value) 450*06c3fb27SDimitry Andric >* = nullptr> 451*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 452*06c3fb27SDimitry Andric explicit 453*06c3fb27SDimitry Andric pair(tuple<_U1, _U2> const& __p) 454*06c3fb27SDimitry Andric : first(std::get<0>(__p)), 455*06c3fb27SDimitry Andric second(std::get<1>(__p)) {} 456*06c3fb27SDimitry Andric 457*06c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 458*06c3fb27SDimitry Andric is_convertible<_U1, _T1>::value && 459*06c3fb27SDimitry Andric is_convertible<_U2, _T2>::value 460*06c3fb27SDimitry Andric >* = nullptr> 461*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 462*06c3fb27SDimitry Andric pair(tuple<_U1, _U2>&& __p) 463*06c3fb27SDimitry Andric : first(std::get<0>(std::move(__p))), 464*06c3fb27SDimitry Andric second(std::get<1>(std::move(__p))) {} 465*06c3fb27SDimitry Andric 466*06c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 467*06c3fb27SDimitry Andric is_constructible<_T1, _U1>::value && 468*06c3fb27SDimitry Andric is_constructible<_T2, _U2>::value && 469*06c3fb27SDimitry Andric !(is_convertible<_U1, _T1>::value && 470*06c3fb27SDimitry Andric is_convertible<_U2, _T2>::value) 471*06c3fb27SDimitry Andric >* = nullptr> 472*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 473*06c3fb27SDimitry Andric explicit 474*06c3fb27SDimitry Andric pair(tuple<_U1, _U2>&& __p) 475*06c3fb27SDimitry Andric : first(std::get<0>(std::move(__p))), 476*06c3fb27SDimitry Andric second(std::get<1>(std::move(__p))) {} 477*06c3fb27SDimitry Andric 478*06c3fb27SDimitry Andric 479*06c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 480*06c3fb27SDimitry Andric is_assignable<_T1&, _U1 const&>::value && 481*06c3fb27SDimitry Andric is_assignable<_T2&, _U2 const&>::value 482*06c3fb27SDimitry Andric >* = nullptr> 483*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 484*06c3fb27SDimitry Andric pair& operator=(tuple<_U1, _U2> const& __p) { 485*06c3fb27SDimitry Andric first = std::get<0>(__p); 486*06c3fb27SDimitry Andric second = std::get<1>(__p); 487*06c3fb27SDimitry Andric return *this; 488*06c3fb27SDimitry Andric } 489*06c3fb27SDimitry Andric 490*06c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 491*06c3fb27SDimitry Andric is_assignable<_T1&, _U1&&>::value && 492*06c3fb27SDimitry Andric is_assignable<_T2&, _U2&&>::value 493*06c3fb27SDimitry Andric >* = nullptr> 494*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 495*06c3fb27SDimitry Andric pair& operator=(tuple<_U1, _U2>&& __p) { 496*06c3fb27SDimitry Andric first = std::get<0>(std::move(__p)); 497*06c3fb27SDimitry Andric second = std::get<1>(std::move(__p)); 498*06c3fb27SDimitry Andric return *this; 499*06c3fb27SDimitry Andric } 500*06c3fb27SDimitry Andric 501*06c3fb27SDimitry Andric // from std::array 502*06c3fb27SDimitry Andric template<class _Up, __enable_if_t< 503*06c3fb27SDimitry Andric is_convertible<_Up const&, _T1>::value && 504*06c3fb27SDimitry Andric is_convertible<_Up const&, _T2>::value 505*06c3fb27SDimitry Andric >* = nullptr> 506*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 507*06c3fb27SDimitry Andric pair(array<_Up, 2> const& __p) 508*06c3fb27SDimitry Andric : first(__p[0]), 509*06c3fb27SDimitry Andric second(__p[1]) {} 510*06c3fb27SDimitry Andric 511*06c3fb27SDimitry Andric template<class _Up, __enable_if_t< 512*06c3fb27SDimitry Andric is_constructible<_T1, _Up const&>::value && 513*06c3fb27SDimitry Andric is_constructible<_T2, _Up const&>::value && 514*06c3fb27SDimitry Andric !(is_convertible<_Up const&, _T1>::value && 515*06c3fb27SDimitry Andric is_convertible<_Up const&, _T2>::value) 516*06c3fb27SDimitry Andric >* = nullptr> 517*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 518*06c3fb27SDimitry Andric explicit 519*06c3fb27SDimitry Andric pair(array<_Up, 2> const& __p) 520*06c3fb27SDimitry Andric : first(__p[0]), 521*06c3fb27SDimitry Andric second(__p[1]) {} 522*06c3fb27SDimitry Andric 523*06c3fb27SDimitry Andric template<class _Up, __enable_if_t< 524*06c3fb27SDimitry Andric is_convertible<_Up, _T1>::value && 525*06c3fb27SDimitry Andric is_convertible<_Up, _T2>::value 526*06c3fb27SDimitry Andric >* = nullptr> 527*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 528*06c3fb27SDimitry Andric pair(array<_Up, 2>&& __p) 529*06c3fb27SDimitry Andric : first(std::move(__p)[0]), 530*06c3fb27SDimitry Andric second(std::move(__p)[1]) {} 531*06c3fb27SDimitry Andric 532*06c3fb27SDimitry Andric template<class _Up, __enable_if_t< 533*06c3fb27SDimitry Andric is_constructible<_T1, _Up>::value && 534*06c3fb27SDimitry Andric is_constructible<_T2, _Up>::value && 535*06c3fb27SDimitry Andric !(is_convertible<_Up, _T1>::value && 536*06c3fb27SDimitry Andric is_convertible<_Up, _T2>::value) 537*06c3fb27SDimitry Andric >* = nullptr> 538*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 539*06c3fb27SDimitry Andric explicit 540*06c3fb27SDimitry Andric pair(array<_Up, 2>&& __p) 541*06c3fb27SDimitry Andric : first(std::move(__p)[0]), 542*06c3fb27SDimitry Andric second(std::move(__p)[1]) {} 543*06c3fb27SDimitry Andric 544*06c3fb27SDimitry Andric 545*06c3fb27SDimitry Andric template<class _Up, __enable_if_t< 546*06c3fb27SDimitry Andric is_assignable<_T1&, _Up const&>::value && 547*06c3fb27SDimitry Andric is_assignable<_T2&, _Up const&>::value 548*06c3fb27SDimitry Andric >* = nullptr> 549*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 550*06c3fb27SDimitry Andric pair& operator=(array<_Up, 2> const& __p) { 551*06c3fb27SDimitry Andric first = std::get<0>(__p); 552*06c3fb27SDimitry Andric second = std::get<1>(__p); 553*06c3fb27SDimitry Andric return *this; 554*06c3fb27SDimitry Andric } 555*06c3fb27SDimitry Andric 556*06c3fb27SDimitry Andric template<class _Up, __enable_if_t< 557*06c3fb27SDimitry Andric is_assignable<_T1&, _Up>::value && 558*06c3fb27SDimitry Andric is_assignable<_T2&, _Up>::value 559*06c3fb27SDimitry Andric >* = nullptr> 560*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 561*06c3fb27SDimitry Andric pair& operator=(array<_Up, 2>&& __p) { 562*06c3fb27SDimitry Andric first = std::get<0>(std::move(__p)); 563*06c3fb27SDimitry Andric second = std::get<1>(std::move(__p)); 564*06c3fb27SDimitry Andric return *this; 565*06c3fb27SDimitry Andric } 566*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER < 23 567*06c3fb27SDimitry Andric #endif // _LIBCPP_CXX03_LANG 568*06c3fb27SDimitry Andric 569*06c3fb27SDimitry 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 { 574*06c3fb27SDimitry Andric using std::swap; 575fe6060f1SDimitry Andric swap(first, __p.first); 576fe6060f1SDimitry Andric swap(second, __p.second); 577fe6060f1SDimitry Andric } 578bdd1243dSDimitry Andric 579*06c3fb27SDimitry 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> 594*06c3fb27SDimitry 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 601*06c3fb27SDimitry 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 608*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 609*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 610fe6060f1SDimitry Andric bool 611*06c3fb27SDimitry 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 616*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 617349cc55cSDimitry Andric 618*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 619349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 620349cc55cSDimitry Andric common_comparison_category_t< 621*06c3fb27SDimitry Andric __synth_three_way_result<_T1, _U1>, 622*06c3fb27SDimitry Andric __synth_three_way_result<_T2, _U2> > 623*06c3fb27SDimitry Andric operator<=>(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 624349cc55cSDimitry Andric { 625*06c3fb27SDimitry Andric if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) { 626349cc55cSDimitry Andric return __c; 627349cc55cSDimitry Andric } 628*06c3fb27SDimitry Andric return std::__synth_three_way(__x.second, __y.second); 629349cc55cSDimitry Andric } 630349cc55cSDimitry Andric 631*06c3fb27SDimitry Andric #else // _LIBCPP_STD_VER >= 20 632349cc55cSDimitry Andric 633*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 634*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 635fe6060f1SDimitry Andric bool 636*06c3fb27SDimitry Andric operator!=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 637fe6060f1SDimitry Andric { 638fe6060f1SDimitry Andric return !(__x == __y); 639fe6060f1SDimitry Andric } 640fe6060f1SDimitry Andric 641*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 642*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 643fe6060f1SDimitry Andric bool 644*06c3fb27SDimitry 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 649*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 650*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 651fe6060f1SDimitry Andric bool 652*06c3fb27SDimitry Andric operator> (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 653fe6060f1SDimitry Andric { 654fe6060f1SDimitry Andric return __y < __x; 655fe6060f1SDimitry Andric } 656fe6060f1SDimitry Andric 657*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 658*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 659fe6060f1SDimitry Andric bool 660*06c3fb27SDimitry Andric operator>=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 661fe6060f1SDimitry Andric { 662fe6060f1SDimitry Andric return !(__x < __y); 663fe6060f1SDimitry Andric } 664fe6060f1SDimitry Andric 665*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 666*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 667fe6060f1SDimitry Andric bool 668*06c3fb27SDimitry Andric operator<=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 669fe6060f1SDimitry Andric { 670fe6060f1SDimitry Andric return !(__y < __x); 671fe6060f1SDimitry Andric } 672fe6060f1SDimitry Andric 673*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 67481ad6265SDimitry Andric 675*06c3fb27SDimitry 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 }; 689*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 23 690349cc55cSDimitry Andric 691fe6060f1SDimitry Andric template <class _T1, class _T2> 692*06c3fb27SDimitry 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 706*06c3fb27SDimitry 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> 719*06c3fb27SDimitry 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> 724*06c3fb27SDimitry 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 { 740*06c3fb27SDimitry 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 { 746*06c3fb27SDimitry 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 756*06c3fb27SDimitry 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 762*06c3fb27SDimitry 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 768*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 769fe6060f1SDimitry Andric _T1&& 770*06c3fb27SDimitry 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 774*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 775fe6060f1SDimitry Andric const _T1&& 776*06c3fb27SDimitry 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 784*06c3fb27SDimitry 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 790*06c3fb27SDimitry 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 796*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 797fe6060f1SDimitry Andric _T2&& 798*06c3fb27SDimitry 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 802*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 803fe6060f1SDimitry Andric const _T2&& 804*06c3fb27SDimitry 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> 808*06c3fb27SDimitry 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> 816*06c3fb27SDimitry 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> 824*06c3fb27SDimitry 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 { 828*06c3fb27SDimitry Andric return __get_pair<_Ip>::get(std::move(__p)); 829fe6060f1SDimitry Andric } 830fe6060f1SDimitry Andric 831fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 832*06c3fb27SDimitry 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 { 836*06c3fb27SDimitry Andric return __get_pair<_Ip>::get(std::move(__p)); 837fe6060f1SDimitry Andric } 838fe6060f1SDimitry Andric 839*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 840fe6060f1SDimitry Andric template <class _T1, class _T2> 841*06c3fb27SDimitry 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> 848*06c3fb27SDimitry 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> 855*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 856fe6060f1SDimitry Andric constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT 857fe6060f1SDimitry Andric { 858*06c3fb27SDimitry Andric return __get_pair<0>::get(std::move(__p)); 859fe6060f1SDimitry Andric } 860fe6060f1SDimitry Andric 861fe6060f1SDimitry Andric template <class _T1, class _T2> 862*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 863fe6060f1SDimitry Andric constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT 864fe6060f1SDimitry Andric { 865*06c3fb27SDimitry Andric return __get_pair<0>::get(std::move(__p)); 866fe6060f1SDimitry Andric } 867fe6060f1SDimitry Andric 868fe6060f1SDimitry Andric template <class _T1, class _T2> 869*06c3fb27SDimitry 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> 876*06c3fb27SDimitry 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> 883*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 884fe6060f1SDimitry Andric constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT 885fe6060f1SDimitry Andric { 886*06c3fb27SDimitry Andric return __get_pair<1>::get(std::move(__p)); 887fe6060f1SDimitry Andric } 888fe6060f1SDimitry Andric 889fe6060f1SDimitry Andric template <class _T1, class _T2> 890*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 891fe6060f1SDimitry Andric constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT 892fe6060f1SDimitry Andric { 893*06c3fb27SDimitry Andric return __get_pair<1>::get(std::move(__p)); 894fe6060f1SDimitry Andric } 895fe6060f1SDimitry Andric 896*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 14 897fe6060f1SDimitry Andric 898fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 899fe6060f1SDimitry Andric 900*06c3fb27SDimitry Andric _LIBCPP_POP_MACROS 901*06c3fb27SDimitry Andric 902fe6060f1SDimitry Andric #endif // _LIBCPP___UTILITY_PAIR_H 903