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 168*5f757f3fSDimitry Andric template<bool _Dummy = true, __enable_if_t<_CheckArgsDep<_Dummy>::__enable_explicit_default(), int> = 0> 16906c3fb27SDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 170fe6060f1SDimitry Andric pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value && 171fe6060f1SDimitry Andric is_nothrow_default_constructible<second_type>::value) 172fe6060f1SDimitry Andric : first(), second() {} 173fe6060f1SDimitry Andric 174*5f757f3fSDimitry Andric template<bool _Dummy = true, __enable_if_t<_CheckArgsDep<_Dummy>::__enable_implicit_default(), int> = 0> 17506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR 176fe6060f1SDimitry Andric pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value && 177fe6060f1SDimitry Andric is_nothrow_default_constructible<second_type>::value) 178fe6060f1SDimitry Andric : first(), second() {} 179fe6060f1SDimitry Andric 180*5f757f3fSDimitry Andric template <bool _Dummy = true, 181*5f757f3fSDimitry Andric __enable_if_t<_CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>(), int> = 0> 18206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 183fe6060f1SDimitry Andric explicit pair(_T1 const& __t1, _T2 const& __t2) 184fe6060f1SDimitry Andric _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && 185fe6060f1SDimitry Andric is_nothrow_copy_constructible<second_type>::value) 186fe6060f1SDimitry Andric : first(__t1), second(__t2) {} 187fe6060f1SDimitry Andric 188*5f757f3fSDimitry Andric template<bool _Dummy = true, 189*5f757f3fSDimitry Andric __enable_if_t<_CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>(), int> = 0> 19006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 191fe6060f1SDimitry Andric pair(_T1 const& __t1, _T2 const& __t2) 192fe6060f1SDimitry Andric _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && 193fe6060f1SDimitry Andric is_nothrow_copy_constructible<second_type>::value) 194fe6060f1SDimitry Andric : first(__t1), second(__t2) {} 195fe6060f1SDimitry Andric 196349cc55cSDimitry Andric template < 19706c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951 198349cc55cSDimitry Andric class _U1 = _T1, class _U2 = _T2, 199349cc55cSDimitry Andric #else 200349cc55cSDimitry Andric class _U1, class _U2, 201349cc55cSDimitry Andric #endif 202*5f757f3fSDimitry Andric __enable_if_t<_CheckArgs::template __enable_explicit<_U1, _U2>(), int> = 0 203349cc55cSDimitry Andric > 20406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 205fe6060f1SDimitry Andric explicit pair(_U1&& __u1, _U2&& __u2) 206fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && 207fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2>::value)) 20806c3fb27SDimitry Andric : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {} 209fe6060f1SDimitry Andric 210349cc55cSDimitry Andric template < 21106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951 212349cc55cSDimitry Andric class _U1 = _T1, class _U2 = _T2, 213349cc55cSDimitry Andric #else 214349cc55cSDimitry Andric class _U1, class _U2, 215349cc55cSDimitry Andric #endif 216*5f757f3fSDimitry Andric __enable_if_t<_CheckArgs::template __enable_implicit<_U1, _U2>(), int> = 0 217349cc55cSDimitry Andric > 21806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 219fe6060f1SDimitry Andric pair(_U1&& __u1, _U2&& __u2) 220fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && 221fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2>::value)) 22206c3fb27SDimitry Andric : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {} 223fe6060f1SDimitry Andric 22406c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 225bdd1243dSDimitry Andric template<class _U1, class _U2, __enable_if_t< 226bdd1243dSDimitry Andric _CheckArgs::template __is_pair_constructible<_U1&, _U2&>() 227bdd1243dSDimitry Andric >* = nullptr> 228bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 229bdd1243dSDimitry Andric explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>()) pair(pair<_U1, _U2>& __p) 230bdd1243dSDimitry Andric noexcept((is_nothrow_constructible<first_type, _U1&>::value && 231bdd1243dSDimitry Andric is_nothrow_constructible<second_type, _U2&>::value)) 232bdd1243dSDimitry Andric : first(__p.first), second(__p.second) {} 233bdd1243dSDimitry Andric #endif 234bdd1243dSDimitry Andric 235*5f757f3fSDimitry Andric template<class _U1, class _U2, __enable_if_t<_CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>(), int> = 0> 23606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 237fe6060f1SDimitry Andric explicit pair(pair<_U1, _U2> const& __p) 238fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && 239fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2 const&>::value)) 240fe6060f1SDimitry Andric : first(__p.first), second(__p.second) {} 241fe6060f1SDimitry Andric 242*5f757f3fSDimitry Andric template<class _U1, class _U2, __enable_if_t<_CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>(), int> = 0> 24306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 244fe6060f1SDimitry Andric pair(pair<_U1, _U2> const& __p) 245fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && 246fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2 const&>::value)) 247fe6060f1SDimitry Andric : first(__p.first), second(__p.second) {} 248fe6060f1SDimitry Andric 249*5f757f3fSDimitry Andric template<class _U1, class _U2, __enable_if_t<_CheckArgs::template __enable_explicit<_U1, _U2>(), int> = 0> 25006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 251fe6060f1SDimitry Andric explicit pair(pair<_U1, _U2>&&__p) 252fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && 253fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2&&>::value)) 25406c3fb27SDimitry Andric : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} 255fe6060f1SDimitry Andric 256*5f757f3fSDimitry Andric template<class _U1, class _U2, __enable_if_t<_CheckArgs::template __enable_implicit<_U1, _U2>(), int> = 0> 25706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 258fe6060f1SDimitry Andric pair(pair<_U1, _U2>&& __p) 259fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && 260fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _U2&&>::value)) 26106c3fb27SDimitry Andric : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} 262fe6060f1SDimitry Andric 26306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 264bdd1243dSDimitry Andric template<class _U1, class _U2, __enable_if_t< 265bdd1243dSDimitry Andric _CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>() 266bdd1243dSDimitry Andric >* = nullptr> 267bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 268bdd1243dSDimitry Andric explicit(!_CheckArgs::template __is_implicit<const _U1&&, const _U2&&>()) 269bdd1243dSDimitry Andric pair(const pair<_U1, _U2>&& __p) 270bdd1243dSDimitry Andric noexcept(is_nothrow_constructible<first_type, const _U1&&>::value && 271bdd1243dSDimitry Andric is_nothrow_constructible<second_type, const _U2&&>::value) 272bdd1243dSDimitry Andric : first(std::move(__p.first)), second(std::move(__p.second)) {} 273bdd1243dSDimitry Andric #endif 274bdd1243dSDimitry Andric 27506c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 27606c3fb27SDimitry Andric // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed. 2773bd749dbSDimitry Andric template <class _PairLike> 27806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() { 2793bd749dbSDimitry Andric if constexpr (__pair_like<_PairLike>) { 28006c3fb27SDimitry Andric return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> || 28106c3fb27SDimitry Andric !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>; 28206c3fb27SDimitry Andric } 28306c3fb27SDimitry Andric return false; 28406c3fb27SDimitry Andric } 285fe6060f1SDimitry Andric 28606c3fb27SDimitry Andric template <__pair_like _PairLike> 287*5f757f3fSDimitry Andric requires(!__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && 288*5f757f3fSDimitry Andric is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike&&>()))> && 28906c3fb27SDimitry Andric is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike&&>()))>) 29006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>()) 29106c3fb27SDimitry Andric pair(_PairLike&& __p) 29206c3fb27SDimitry Andric : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {} 29306c3fb27SDimitry Andric # endif 294fe6060f1SDimitry Andric 295fe6060f1SDimitry Andric template <class... _Args1, class... _Args2> 29606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 297fe6060f1SDimitry Andric pair(piecewise_construct_t __pc, 298fe6060f1SDimitry Andric tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) 299fe6060f1SDimitry Andric _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value && 300fe6060f1SDimitry Andric is_nothrow_constructible<second_type, _Args2...>::value)) 301fe6060f1SDimitry Andric : pair(__pc, __first_args, __second_args, 302fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Args1)>::type(), 303fe6060f1SDimitry Andric typename __make_tuple_indices<sizeof...(_Args2) >::type()) {} 304fe6060f1SDimitry Andric 30506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 306bdd1243dSDimitry Andric pair& operator=(__conditional_t< 307fe6060f1SDimitry Andric is_copy_assignable<first_type>::value && 308fe6060f1SDimitry Andric is_copy_assignable<second_type>::value, 309bdd1243dSDimitry Andric pair, __nat> const& __p) 310fe6060f1SDimitry Andric _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value && 311fe6060f1SDimitry Andric is_nothrow_copy_assignable<second_type>::value) 312fe6060f1SDimitry Andric { 313fe6060f1SDimitry Andric first = __p.first; 314fe6060f1SDimitry Andric second = __p.second; 315fe6060f1SDimitry Andric return *this; 316fe6060f1SDimitry Andric } 317fe6060f1SDimitry Andric 31806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 319bdd1243dSDimitry Andric pair& operator=(__conditional_t< 320fe6060f1SDimitry Andric is_move_assignable<first_type>::value && 321fe6060f1SDimitry Andric is_move_assignable<second_type>::value, 322bdd1243dSDimitry Andric pair, __nat>&& __p) 323fe6060f1SDimitry Andric _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value && 324fe6060f1SDimitry Andric is_nothrow_move_assignable<second_type>::value) 325fe6060f1SDimitry Andric { 32606c3fb27SDimitry Andric first = std::forward<first_type>(__p.first); 32706c3fb27SDimitry Andric second = std::forward<second_type>(__p.second); 328fe6060f1SDimitry Andric return *this; 329fe6060f1SDimitry Andric } 330fe6060f1SDimitry Andric 33106c3fb27SDimitry Andric template <class _U1, class _U2, __enable_if_t< 33206c3fb27SDimitry Andric is_assignable<first_type&, _U1 const&>::value && 33306c3fb27SDimitry Andric is_assignable<second_type&, _U2 const&>::value 33406c3fb27SDimitry Andric >* = nullptr> 33506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 33606c3fb27SDimitry Andric pair& operator=(pair<_U1, _U2> const& __p) { 33706c3fb27SDimitry Andric first = __p.first; 33806c3fb27SDimitry Andric second = __p.second; 33906c3fb27SDimitry Andric return *this; 34006c3fb27SDimitry Andric } 34106c3fb27SDimitry Andric 34206c3fb27SDimitry Andric template <class _U1, class _U2, __enable_if_t< 34306c3fb27SDimitry Andric is_assignable<first_type&, _U1>::value && 34406c3fb27SDimitry Andric is_assignable<second_type&, _U2>::value 34506c3fb27SDimitry Andric >* = nullptr> 34606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 34706c3fb27SDimitry Andric pair& operator=(pair<_U1, _U2>&& __p) { 34806c3fb27SDimitry Andric first = std::forward<_U1>(__p.first); 34906c3fb27SDimitry Andric second = std::forward<_U2>(__p.second); 35006c3fb27SDimitry Andric return *this; 35106c3fb27SDimitry Andric } 35206c3fb27SDimitry Andric 35306c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 354bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 355bdd1243dSDimitry Andric const pair& operator=(pair const& __p) const 356bdd1243dSDimitry Andric noexcept(is_nothrow_copy_assignable_v<const first_type> && 357bdd1243dSDimitry Andric is_nothrow_copy_assignable_v<const second_type>) 358bdd1243dSDimitry Andric requires(is_copy_assignable_v<const first_type> && 359bdd1243dSDimitry Andric is_copy_assignable_v<const second_type>) { 360bdd1243dSDimitry Andric first = __p.first; 361bdd1243dSDimitry Andric second = __p.second; 362bdd1243dSDimitry Andric return *this; 363bdd1243dSDimitry Andric } 364bdd1243dSDimitry Andric 365bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 366bdd1243dSDimitry Andric const pair& operator=(pair&& __p) const 367bdd1243dSDimitry Andric noexcept(is_nothrow_assignable_v<const first_type&, first_type> && 368bdd1243dSDimitry Andric is_nothrow_assignable_v<const second_type&, second_type>) 369bdd1243dSDimitry Andric requires(is_assignable_v<const first_type&, first_type> && 370bdd1243dSDimitry Andric is_assignable_v<const second_type&, second_type>) { 371bdd1243dSDimitry Andric first = std::forward<first_type>(__p.first); 372bdd1243dSDimitry Andric second = std::forward<second_type>(__p.second); 373bdd1243dSDimitry Andric return *this; 374bdd1243dSDimitry Andric } 375bdd1243dSDimitry Andric 376bdd1243dSDimitry Andric template<class _U1, class _U2> 377bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 378bdd1243dSDimitry Andric const pair& operator=(const pair<_U1, _U2>& __p) const 379bdd1243dSDimitry Andric requires(is_assignable_v<const first_type&, const _U1&> && 380bdd1243dSDimitry Andric is_assignable_v<const second_type&, const _U2&>) { 381bdd1243dSDimitry Andric first = __p.first; 382bdd1243dSDimitry Andric second = __p.second; 383bdd1243dSDimitry Andric return *this; 384bdd1243dSDimitry Andric } 385bdd1243dSDimitry Andric 386bdd1243dSDimitry Andric template<class _U1, class _U2> 387bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 388bdd1243dSDimitry Andric const pair& operator=(pair<_U1, _U2>&& __p) const 389bdd1243dSDimitry Andric requires(is_assignable_v<const first_type&, _U1> && 390bdd1243dSDimitry Andric is_assignable_v<const second_type&, _U2>) { 391bdd1243dSDimitry Andric first = std::forward<_U1>(__p.first); 392bdd1243dSDimitry Andric second = std::forward<_U2>(__p.second); 393bdd1243dSDimitry Andric return *this; 394bdd1243dSDimitry Andric } 395bdd1243dSDimitry Andric 39606c3fb27SDimitry Andric template <__pair_like _PairLike> 39706c3fb27SDimitry Andric requires(__different_from<_PairLike, pair> && 39806c3fb27SDimitry Andric !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && 39906c3fb27SDimitry Andric is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> && 40006c3fb27SDimitry Andric is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>) 40106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) { 40206c3fb27SDimitry Andric first = std::get<0>(std::forward<_PairLike>(__p)); 40306c3fb27SDimitry Andric second = std::get<1>(std::forward<_PairLike>(__p)); 404fe6060f1SDimitry Andric return *this; 405fe6060f1SDimitry Andric } 406fe6060f1SDimitry Andric 40706c3fb27SDimitry Andric template <__pair_like _PairLike> 40806c3fb27SDimitry Andric requires(__different_from<_PairLike, pair> && 40906c3fb27SDimitry Andric !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && 41006c3fb27SDimitry Andric is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> && 41106c3fb27SDimitry Andric is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>) 41206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const { 41306c3fb27SDimitry Andric first = std::get<0>(std::forward<_PairLike>(__p)); 41406c3fb27SDimitry Andric second = std::get<1>(std::forward<_PairLike>(__p)); 41506c3fb27SDimitry Andric return *this; 41606c3fb27SDimitry Andric } 41706c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER >= 23 41806c3fb27SDimitry Andric 41906c3fb27SDimitry Andric // Prior to C++23, we provide an approximation of constructors and assignment operators from 42006c3fb27SDimitry Andric // pair-like types. This was historically provided as an extension. 42106c3fb27SDimitry Andric #if _LIBCPP_STD_VER < 23 42206c3fb27SDimitry Andric // from std::tuple 42306c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 42406c3fb27SDimitry Andric is_convertible<_U1 const&, _T1>::value && 42506c3fb27SDimitry Andric is_convertible<_U2 const&, _T2>::value 42606c3fb27SDimitry Andric >* = nullptr> 42706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 42806c3fb27SDimitry Andric pair(tuple<_U1, _U2> const& __p) 42906c3fb27SDimitry Andric : first(std::get<0>(__p)), 43006c3fb27SDimitry Andric second(std::get<1>(__p)) {} 43106c3fb27SDimitry Andric 43206c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 43306c3fb27SDimitry Andric is_constructible<_T1, _U1 const&>::value && 43406c3fb27SDimitry Andric is_constructible<_T2, _U2 const&>::value && 43506c3fb27SDimitry Andric !(is_convertible<_U1 const&, _T1>::value && 43606c3fb27SDimitry Andric is_convertible<_U2 const&, _T2>::value) 43706c3fb27SDimitry Andric >* = nullptr> 43806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 43906c3fb27SDimitry Andric explicit 44006c3fb27SDimitry Andric pair(tuple<_U1, _U2> const& __p) 44106c3fb27SDimitry Andric : first(std::get<0>(__p)), 44206c3fb27SDimitry Andric second(std::get<1>(__p)) {} 44306c3fb27SDimitry Andric 44406c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 44506c3fb27SDimitry Andric is_convertible<_U1, _T1>::value && 44606c3fb27SDimitry Andric is_convertible<_U2, _T2>::value 44706c3fb27SDimitry Andric >* = nullptr> 44806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 44906c3fb27SDimitry Andric pair(tuple<_U1, _U2>&& __p) 45006c3fb27SDimitry Andric : first(std::get<0>(std::move(__p))), 45106c3fb27SDimitry Andric second(std::get<1>(std::move(__p))) {} 45206c3fb27SDimitry Andric 45306c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 45406c3fb27SDimitry Andric is_constructible<_T1, _U1>::value && 45506c3fb27SDimitry Andric is_constructible<_T2, _U2>::value && 45606c3fb27SDimitry Andric !(is_convertible<_U1, _T1>::value && 45706c3fb27SDimitry Andric is_convertible<_U2, _T2>::value) 45806c3fb27SDimitry Andric >* = nullptr> 45906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 46006c3fb27SDimitry Andric explicit 46106c3fb27SDimitry Andric pair(tuple<_U1, _U2>&& __p) 46206c3fb27SDimitry Andric : first(std::get<0>(std::move(__p))), 46306c3fb27SDimitry Andric second(std::get<1>(std::move(__p))) {} 46406c3fb27SDimitry Andric 46506c3fb27SDimitry Andric 46606c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 46706c3fb27SDimitry Andric is_assignable<_T1&, _U1 const&>::value && 46806c3fb27SDimitry Andric is_assignable<_T2&, _U2 const&>::value 46906c3fb27SDimitry Andric >* = nullptr> 47006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 47106c3fb27SDimitry Andric pair& operator=(tuple<_U1, _U2> const& __p) { 47206c3fb27SDimitry Andric first = std::get<0>(__p); 47306c3fb27SDimitry Andric second = std::get<1>(__p); 47406c3fb27SDimitry Andric return *this; 47506c3fb27SDimitry Andric } 47606c3fb27SDimitry Andric 47706c3fb27SDimitry Andric template<class _U1, class _U2, __enable_if_t< 47806c3fb27SDimitry Andric is_assignable<_T1&, _U1&&>::value && 47906c3fb27SDimitry Andric is_assignable<_T2&, _U2&&>::value 48006c3fb27SDimitry Andric >* = nullptr> 48106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 48206c3fb27SDimitry Andric pair& operator=(tuple<_U1, _U2>&& __p) { 48306c3fb27SDimitry Andric first = std::get<0>(std::move(__p)); 48406c3fb27SDimitry Andric second = std::get<1>(std::move(__p)); 48506c3fb27SDimitry Andric return *this; 48606c3fb27SDimitry Andric } 48706c3fb27SDimitry Andric 48806c3fb27SDimitry Andric // from std::array 48906c3fb27SDimitry Andric template<class _Up, __enable_if_t< 49006c3fb27SDimitry Andric is_convertible<_Up const&, _T1>::value && 49106c3fb27SDimitry Andric is_convertible<_Up const&, _T2>::value 49206c3fb27SDimitry Andric >* = nullptr> 49306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 49406c3fb27SDimitry Andric pair(array<_Up, 2> const& __p) 49506c3fb27SDimitry Andric : first(__p[0]), 49606c3fb27SDimitry Andric second(__p[1]) {} 49706c3fb27SDimitry Andric 49806c3fb27SDimitry Andric template<class _Up, __enable_if_t< 49906c3fb27SDimitry Andric is_constructible<_T1, _Up const&>::value && 50006c3fb27SDimitry Andric is_constructible<_T2, _Up const&>::value && 50106c3fb27SDimitry Andric !(is_convertible<_Up const&, _T1>::value && 50206c3fb27SDimitry Andric is_convertible<_Up const&, _T2>::value) 50306c3fb27SDimitry Andric >* = nullptr> 50406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 50506c3fb27SDimitry Andric explicit 50606c3fb27SDimitry Andric pair(array<_Up, 2> const& __p) 50706c3fb27SDimitry Andric : first(__p[0]), 50806c3fb27SDimitry Andric second(__p[1]) {} 50906c3fb27SDimitry Andric 51006c3fb27SDimitry Andric template<class _Up, __enable_if_t< 51106c3fb27SDimitry Andric is_convertible<_Up, _T1>::value && 51206c3fb27SDimitry Andric is_convertible<_Up, _T2>::value 51306c3fb27SDimitry Andric >* = nullptr> 51406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 51506c3fb27SDimitry Andric pair(array<_Up, 2>&& __p) 51606c3fb27SDimitry Andric : first(std::move(__p)[0]), 51706c3fb27SDimitry Andric second(std::move(__p)[1]) {} 51806c3fb27SDimitry Andric 51906c3fb27SDimitry Andric template<class _Up, __enable_if_t< 52006c3fb27SDimitry Andric is_constructible<_T1, _Up>::value && 52106c3fb27SDimitry Andric is_constructible<_T2, _Up>::value && 52206c3fb27SDimitry Andric !(is_convertible<_Up, _T1>::value && 52306c3fb27SDimitry Andric is_convertible<_Up, _T2>::value) 52406c3fb27SDimitry Andric >* = nullptr> 52506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 52606c3fb27SDimitry Andric explicit 52706c3fb27SDimitry Andric pair(array<_Up, 2>&& __p) 52806c3fb27SDimitry Andric : first(std::move(__p)[0]), 52906c3fb27SDimitry Andric second(std::move(__p)[1]) {} 53006c3fb27SDimitry Andric 53106c3fb27SDimitry Andric 53206c3fb27SDimitry Andric template<class _Up, __enable_if_t< 53306c3fb27SDimitry Andric is_assignable<_T1&, _Up const&>::value && 53406c3fb27SDimitry Andric is_assignable<_T2&, _Up const&>::value 53506c3fb27SDimitry Andric >* = nullptr> 53606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 53706c3fb27SDimitry Andric pair& operator=(array<_Up, 2> const& __p) { 53806c3fb27SDimitry Andric first = std::get<0>(__p); 53906c3fb27SDimitry Andric second = std::get<1>(__p); 54006c3fb27SDimitry Andric return *this; 54106c3fb27SDimitry Andric } 54206c3fb27SDimitry Andric 54306c3fb27SDimitry Andric template<class _Up, __enable_if_t< 54406c3fb27SDimitry Andric is_assignable<_T1&, _Up>::value && 54506c3fb27SDimitry Andric is_assignable<_T2&, _Up>::value 54606c3fb27SDimitry Andric >* = nullptr> 54706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 54806c3fb27SDimitry Andric pair& operator=(array<_Up, 2>&& __p) { 54906c3fb27SDimitry Andric first = std::get<0>(std::move(__p)); 55006c3fb27SDimitry Andric second = std::get<1>(std::move(__p)); 55106c3fb27SDimitry Andric return *this; 55206c3fb27SDimitry Andric } 55306c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER < 23 55406c3fb27SDimitry Andric #endif // _LIBCPP_CXX03_LANG 55506c3fb27SDimitry Andric 55606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 557fe6060f1SDimitry Andric void 558fe6060f1SDimitry Andric swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value && 559fe6060f1SDimitry Andric __is_nothrow_swappable<second_type>::value) 560fe6060f1SDimitry Andric { 56106c3fb27SDimitry Andric using std::swap; 562fe6060f1SDimitry Andric swap(first, __p.first); 563fe6060f1SDimitry Andric swap(second, __p.second); 564fe6060f1SDimitry Andric } 565bdd1243dSDimitry Andric 56606c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 567bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 568bdd1243dSDimitry Andric void swap(const pair& __p) const 569bdd1243dSDimitry Andric noexcept(__is_nothrow_swappable<const first_type>::value && 570bdd1243dSDimitry Andric __is_nothrow_swappable<const second_type>::value) 571bdd1243dSDimitry Andric { 572bdd1243dSDimitry Andric using std::swap; 573bdd1243dSDimitry Andric swap(first, __p.first); 574bdd1243dSDimitry Andric swap(second, __p.second); 575bdd1243dSDimitry Andric } 576bdd1243dSDimitry Andric #endif 577fe6060f1SDimitry Andric private: 578fe6060f1SDimitry Andric 579fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 580fe6060f1SDimitry Andric template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> 58106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 582fe6060f1SDimitry Andric pair(piecewise_construct_t, 583fe6060f1SDimitry Andric tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, 584fe6060f1SDimitry Andric __tuple_indices<_I1...>, __tuple_indices<_I2...>); 585fe6060f1SDimitry Andric #endif 586fe6060f1SDimitry Andric }; 587fe6060f1SDimitry Andric 58806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 17 589fe6060f1SDimitry Andric template<class _T1, class _T2> 590fe6060f1SDimitry Andric pair(_T1, _T2) -> pair<_T1, _T2>; 591349cc55cSDimitry Andric #endif 592349cc55cSDimitry Andric 593349cc55cSDimitry Andric // [pairs.spec], specialized algorithms 594fe6060f1SDimitry Andric 59506c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 59606c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 597fe6060f1SDimitry Andric bool 59806c3fb27SDimitry Andric operator==(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 599fe6060f1SDimitry Andric { 600fe6060f1SDimitry Andric return __x.first == __y.first && __x.second == __y.second; 601fe6060f1SDimitry Andric } 602fe6060f1SDimitry Andric 60306c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 604349cc55cSDimitry Andric 60506c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 606349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 607349cc55cSDimitry Andric common_comparison_category_t< 60806c3fb27SDimitry Andric __synth_three_way_result<_T1, _U1>, 60906c3fb27SDimitry Andric __synth_three_way_result<_T2, _U2> > 61006c3fb27SDimitry Andric operator<=>(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 611349cc55cSDimitry Andric { 61206c3fb27SDimitry Andric if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) { 613349cc55cSDimitry Andric return __c; 614349cc55cSDimitry Andric } 61506c3fb27SDimitry Andric return std::__synth_three_way(__x.second, __y.second); 616349cc55cSDimitry Andric } 617349cc55cSDimitry Andric 61806c3fb27SDimitry Andric #else // _LIBCPP_STD_VER >= 20 619349cc55cSDimitry Andric 62006c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 62106c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 622fe6060f1SDimitry Andric bool 62306c3fb27SDimitry Andric operator!=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 624fe6060f1SDimitry Andric { 625fe6060f1SDimitry Andric return !(__x == __y); 626fe6060f1SDimitry Andric } 627fe6060f1SDimitry Andric 62806c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 62906c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 630fe6060f1SDimitry Andric bool 63106c3fb27SDimitry Andric operator< (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 632fe6060f1SDimitry Andric { 633fe6060f1SDimitry Andric return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second); 634fe6060f1SDimitry Andric } 635fe6060f1SDimitry Andric 63606c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 63706c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 638fe6060f1SDimitry Andric bool 63906c3fb27SDimitry Andric operator> (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 640fe6060f1SDimitry Andric { 641fe6060f1SDimitry Andric return __y < __x; 642fe6060f1SDimitry Andric } 643fe6060f1SDimitry Andric 64406c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 64506c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 646fe6060f1SDimitry Andric bool 64706c3fb27SDimitry Andric operator>=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 648fe6060f1SDimitry Andric { 649fe6060f1SDimitry Andric return !(__x < __y); 650fe6060f1SDimitry Andric } 651fe6060f1SDimitry Andric 65206c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 65306c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 654fe6060f1SDimitry Andric bool 65506c3fb27SDimitry Andric operator<=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) 656fe6060f1SDimitry Andric { 657fe6060f1SDimitry Andric return !(__y < __x); 658fe6060f1SDimitry Andric } 659fe6060f1SDimitry Andric 66006c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20 66181ad6265SDimitry Andric 66206c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 66381ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2, template<class> class _TQual, template<class> class _UQual> 66481ad6265SDimitry Andric requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, 66581ad6265SDimitry Andric common_reference_t<_TQual<_T2>, _UQual<_U2>>>; } 66681ad6265SDimitry Andric struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> { 66781ad6265SDimitry Andric using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, 66881ad6265SDimitry Andric common_reference_t<_TQual<_T2>, _UQual<_U2>>>; 66981ad6265SDimitry Andric }; 67081ad6265SDimitry Andric 67181ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2> 67281ad6265SDimitry Andric requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; } 67381ad6265SDimitry Andric struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> { 67481ad6265SDimitry Andric using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; 67581ad6265SDimitry Andric }; 67606c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 23 677349cc55cSDimitry Andric 678*5f757f3fSDimitry Andric template <class _T1, class _T2, __enable_if_t<__is_swappable<_T1>::value && __is_swappable<_T2>::value, int> = 0> 67906c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 680fe6060f1SDimitry Andric void 681fe6060f1SDimitry Andric swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) 682fe6060f1SDimitry Andric _NOEXCEPT_((__is_nothrow_swappable<_T1>::value && 683fe6060f1SDimitry Andric __is_nothrow_swappable<_T2>::value)) 684fe6060f1SDimitry Andric { 685fe6060f1SDimitry Andric __x.swap(__y); 686fe6060f1SDimitry Andric } 687fe6060f1SDimitry Andric 68806c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 689bdd1243dSDimitry Andric template <class _T1, class _T2> 690bdd1243dSDimitry Andric requires (__is_swappable<const _T1>::value && 691bdd1243dSDimitry Andric __is_swappable<const _T2>::value) 692bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr 693bdd1243dSDimitry Andric void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) 694bdd1243dSDimitry Andric noexcept(noexcept(__x.swap(__y))) 695bdd1243dSDimitry Andric { 696bdd1243dSDimitry Andric __x.swap(__y); 697bdd1243dSDimitry Andric } 698bdd1243dSDimitry Andric #endif 699fe6060f1SDimitry Andric 700fe6060f1SDimitry Andric template <class _T1, class _T2> 70106c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 702fe6060f1SDimitry Andric pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> 703fe6060f1SDimitry Andric make_pair(_T1&& __t1, _T2&& __t2) 704fe6060f1SDimitry Andric { 705fe6060f1SDimitry Andric return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> 70606c3fb27SDimitry Andric (std::forward<_T1>(__t1), std::forward<_T2>(__t2)); 707fe6060f1SDimitry Andric } 708fe6060f1SDimitry Andric 709fe6060f1SDimitry Andric template <class _T1, class _T2> 710fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > 711fe6060f1SDimitry Andric : public integral_constant<size_t, 2> {}; 712fe6060f1SDimitry Andric 713fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 714fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> > 715fe6060f1SDimitry Andric { 716fe6060f1SDimitry Andric static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>"); 717fe6060f1SDimitry Andric }; 718fe6060f1SDimitry Andric 719fe6060f1SDimitry Andric template <class _T1, class _T2> 720fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > 721fe6060f1SDimitry Andric { 72206c3fb27SDimitry Andric using type _LIBCPP_NODEBUG = _T1; 723fe6060f1SDimitry Andric }; 724fe6060f1SDimitry Andric 725fe6060f1SDimitry Andric template <class _T1, class _T2> 726fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > 727fe6060f1SDimitry Andric { 72806c3fb27SDimitry Andric using type _LIBCPP_NODEBUG = _T2; 729fe6060f1SDimitry Andric }; 730fe6060f1SDimitry Andric 731fe6060f1SDimitry Andric template <size_t _Ip> struct __get_pair; 732fe6060f1SDimitry Andric 733fe6060f1SDimitry Andric template <> 734fe6060f1SDimitry Andric struct __get_pair<0> 735fe6060f1SDimitry Andric { 736fe6060f1SDimitry Andric template <class _T1, class _T2> 737fe6060f1SDimitry Andric static 73806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 739fe6060f1SDimitry Andric _T1& 740fe6060f1SDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} 741fe6060f1SDimitry Andric 742fe6060f1SDimitry Andric template <class _T1, class _T2> 743fe6060f1SDimitry Andric static 74406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 745fe6060f1SDimitry Andric const _T1& 746fe6060f1SDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} 747fe6060f1SDimitry Andric 748fe6060f1SDimitry Andric template <class _T1, class _T2> 749fe6060f1SDimitry Andric static 75006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 751fe6060f1SDimitry Andric _T1&& 75206c3fb27SDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T1>(__p.first);} 753fe6060f1SDimitry Andric 754fe6060f1SDimitry Andric template <class _T1, class _T2> 755fe6060f1SDimitry Andric static 75606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 757fe6060f1SDimitry Andric const _T1&& 75806c3fb27SDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T1>(__p.first);} 759fe6060f1SDimitry Andric }; 760fe6060f1SDimitry Andric 761fe6060f1SDimitry Andric template <> 762fe6060f1SDimitry Andric struct __get_pair<1> 763fe6060f1SDimitry Andric { 764fe6060f1SDimitry Andric template <class _T1, class _T2> 765fe6060f1SDimitry Andric static 76606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 767fe6060f1SDimitry Andric _T2& 768fe6060f1SDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} 769fe6060f1SDimitry Andric 770fe6060f1SDimitry Andric template <class _T1, class _T2> 771fe6060f1SDimitry Andric static 77206c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 773fe6060f1SDimitry Andric const _T2& 774fe6060f1SDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} 775fe6060f1SDimitry Andric 776fe6060f1SDimitry Andric template <class _T1, class _T2> 777fe6060f1SDimitry Andric static 77806c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 779fe6060f1SDimitry Andric _T2&& 78006c3fb27SDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T2>(__p.second);} 781fe6060f1SDimitry Andric 782fe6060f1SDimitry Andric template <class _T1, class _T2> 783fe6060f1SDimitry Andric static 78406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 785fe6060f1SDimitry Andric const _T2&& 78606c3fb27SDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T2>(__p.second);} 787fe6060f1SDimitry Andric }; 788fe6060f1SDimitry Andric 789fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 79006c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 791fe6060f1SDimitry Andric typename tuple_element<_Ip, pair<_T1, _T2> >::type& 792fe6060f1SDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT 793fe6060f1SDimitry Andric { 794fe6060f1SDimitry Andric return __get_pair<_Ip>::get(__p); 795fe6060f1SDimitry Andric } 796fe6060f1SDimitry Andric 797fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 79806c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 799fe6060f1SDimitry Andric const typename tuple_element<_Ip, pair<_T1, _T2> >::type& 800fe6060f1SDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT 801fe6060f1SDimitry Andric { 802fe6060f1SDimitry Andric return __get_pair<_Ip>::get(__p); 803fe6060f1SDimitry Andric } 804fe6060f1SDimitry Andric 805fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 80606c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 807fe6060f1SDimitry Andric typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 808fe6060f1SDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT 809fe6060f1SDimitry Andric { 81006c3fb27SDimitry Andric return __get_pair<_Ip>::get(std::move(__p)); 811fe6060f1SDimitry Andric } 812fe6060f1SDimitry Andric 813fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2> 81406c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 815fe6060f1SDimitry Andric const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& 816fe6060f1SDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT 817fe6060f1SDimitry Andric { 81806c3fb27SDimitry Andric return __get_pair<_Ip>::get(std::move(__p)); 819fe6060f1SDimitry Andric } 820fe6060f1SDimitry Andric 82106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14 822fe6060f1SDimitry Andric template <class _T1, class _T2> 82306c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 824fe6060f1SDimitry Andric constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT 825fe6060f1SDimitry Andric { 826fe6060f1SDimitry Andric return __get_pair<0>::get(__p); 827fe6060f1SDimitry Andric } 828fe6060f1SDimitry Andric 829fe6060f1SDimitry Andric template <class _T1, class _T2> 83006c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 831fe6060f1SDimitry Andric constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT 832fe6060f1SDimitry Andric { 833fe6060f1SDimitry Andric return __get_pair<0>::get(__p); 834fe6060f1SDimitry Andric } 835fe6060f1SDimitry Andric 836fe6060f1SDimitry Andric template <class _T1, class _T2> 83706c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 838fe6060f1SDimitry Andric constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT 839fe6060f1SDimitry Andric { 84006c3fb27SDimitry Andric return __get_pair<0>::get(std::move(__p)); 841fe6060f1SDimitry Andric } 842fe6060f1SDimitry Andric 843fe6060f1SDimitry Andric template <class _T1, class _T2> 84406c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 845fe6060f1SDimitry Andric constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT 846fe6060f1SDimitry Andric { 84706c3fb27SDimitry Andric return __get_pair<0>::get(std::move(__p)); 848fe6060f1SDimitry Andric } 849fe6060f1SDimitry Andric 850fe6060f1SDimitry Andric template <class _T1, class _T2> 85106c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 852fe6060f1SDimitry Andric constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT 853fe6060f1SDimitry Andric { 854fe6060f1SDimitry Andric return __get_pair<1>::get(__p); 855fe6060f1SDimitry Andric } 856fe6060f1SDimitry Andric 857fe6060f1SDimitry Andric template <class _T1, class _T2> 85806c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 859fe6060f1SDimitry Andric constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT 860fe6060f1SDimitry Andric { 861fe6060f1SDimitry Andric return __get_pair<1>::get(__p); 862fe6060f1SDimitry Andric } 863fe6060f1SDimitry Andric 864fe6060f1SDimitry Andric template <class _T1, class _T2> 86506c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 866fe6060f1SDimitry Andric constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT 867fe6060f1SDimitry Andric { 86806c3fb27SDimitry Andric return __get_pair<1>::get(std::move(__p)); 869fe6060f1SDimitry Andric } 870fe6060f1SDimitry Andric 871fe6060f1SDimitry Andric template <class _T1, class _T2> 87206c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI 873fe6060f1SDimitry Andric constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT 874fe6060f1SDimitry Andric { 87506c3fb27SDimitry Andric return __get_pair<1>::get(std::move(__p)); 876fe6060f1SDimitry Andric } 877fe6060f1SDimitry Andric 87806c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 14 879fe6060f1SDimitry Andric 880fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 881fe6060f1SDimitry Andric 88206c3fb27SDimitry Andric _LIBCPP_POP_MACROS 88306c3fb27SDimitry Andric 884fe6060f1SDimitry Andric #endif // _LIBCPP___UTILITY_PAIR_H 885