Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:14:07

0001 //===----------------------------------------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef _LIBCPP___UTILITY_PAIR_H
0010 #define _LIBCPP___UTILITY_PAIR_H
0011 
0012 #include <__compare/common_comparison_category.h>
0013 #include <__compare/synth_three_way.h>
0014 #include <__concepts/different_from.h>
0015 #include <__config>
0016 #include <__cstddef/size_t.h>
0017 #include <__fwd/array.h>
0018 #include <__fwd/pair.h>
0019 #include <__fwd/tuple.h>
0020 #include <__tuple/tuple_indices.h>
0021 #include <__tuple/tuple_like_no_subrange.h>
0022 #include <__tuple/tuple_size.h>
0023 #include <__type_traits/common_reference.h>
0024 #include <__type_traits/common_type.h>
0025 #include <__type_traits/conditional.h>
0026 #include <__type_traits/decay.h>
0027 #include <__type_traits/enable_if.h>
0028 #include <__type_traits/integral_constant.h>
0029 #include <__type_traits/is_assignable.h>
0030 #include <__type_traits/is_constructible.h>
0031 #include <__type_traits/is_convertible.h>
0032 #include <__type_traits/is_implicitly_default_constructible.h>
0033 #include <__type_traits/is_nothrow_assignable.h>
0034 #include <__type_traits/is_nothrow_constructible.h>
0035 #include <__type_traits/is_same.h>
0036 #include <__type_traits/is_swappable.h>
0037 #include <__type_traits/is_trivially_relocatable.h>
0038 #include <__type_traits/nat.h>
0039 #include <__type_traits/remove_cvref.h>
0040 #include <__type_traits/unwrap_ref.h>
0041 #include <__utility/declval.h>
0042 #include <__utility/forward.h>
0043 #include <__utility/move.h>
0044 #include <__utility/piecewise_construct.h>
0045 
0046 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0047 #  pragma GCC system_header
0048 #endif
0049 
0050 _LIBCPP_PUSH_MACROS
0051 #include <__undef_macros>
0052 
0053 _LIBCPP_BEGIN_NAMESPACE_STD
0054 
0055 template <class, class>
0056 struct __non_trivially_copyable_base {
0057   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __non_trivially_copyable_base() _NOEXCEPT {}
0058   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
0059   __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
0060 };
0061 
0062 template <class _T1, class _T2>
0063 struct _LIBCPP_TEMPLATE_VIS pair
0064 #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
0065     : private __non_trivially_copyable_base<_T1, _T2>
0066 #endif
0067 {
0068   using first_type  = _T1;
0069   using second_type = _T2;
0070 
0071   _T1 first;
0072   _T2 second;
0073 
0074   using __trivially_relocatable _LIBCPP_NODEBUG =
0075       __conditional_t<__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value,
0076                       pair,
0077                       void>;
0078 
0079   _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
0080   _LIBCPP_HIDE_FROM_ABI pair(pair&&)      = default;
0081 
0082 #ifdef _LIBCPP_CXX03_LANG
0083   _LIBCPP_HIDE_FROM_ABI pair() : first(), second() {}
0084 
0085   _LIBCPP_HIDE_FROM_ABI pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
0086 
0087   template <class _U1, class _U2>
0088   _LIBCPP_HIDE_FROM_ABI pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
0089 
0090   _LIBCPP_HIDE_FROM_ABI pair& operator=(pair const& __p) {
0091     first  = __p.first;
0092     second = __p.second;
0093     return *this;
0094   }
0095 
0096   // Extension: This is provided in C++03 because it allows properly handling the
0097   //            assignment to a pair containing references, which would be a hard
0098   //            error otherwise.
0099   template <
0100       class _U1,
0101       class _U2,
0102       __enable_if_t<is_assignable<first_type&, _U1 const&>::value && is_assignable<second_type&, _U2 const&>::value,
0103                     int> = 0>
0104   _LIBCPP_HIDE_FROM_ABI pair& operator=(pair<_U1, _U2> const& __p) {
0105     first  = __p.first;
0106     second = __p.second;
0107     return *this;
0108   }
0109 #else
0110   struct _CheckArgs {
0111     template <int&...>
0112     static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() {
0113       return __is_implicitly_default_constructible<_T1>::value && __is_implicitly_default_constructible<_T2>::value;
0114     }
0115 
0116     template <int&...>
0117     static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_default() {
0118       return is_default_constructible<_T1>::value && is_default_constructible<_T2>::value;
0119     }
0120 
0121     template <class _U1, class _U2>
0122     static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() {
0123       return is_constructible<first_type, _U1>::value && is_constructible<second_type, _U2>::value;
0124     }
0125 
0126     template <class _U1, class _U2>
0127     static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() {
0128       return is_convertible<_U1, first_type>::value && is_convertible<_U2, second_type>::value;
0129     }
0130   };
0131 
0132   template <bool _MaybeEnable>
0133   using _CheckArgsDep _LIBCPP_NODEBUG = __conditional_t<_MaybeEnable, _CheckArgs, void>;
0134 
0135   template <bool _Dummy = true, __enable_if_t<_CheckArgsDep<_Dummy>::__enable_default(), int> = 0>
0136   explicit(!_CheckArgsDep<_Dummy>::__enable_implicit_default()) _LIBCPP_HIDE_FROM_ABI constexpr pair() noexcept(
0137       is_nothrow_default_constructible<first_type>::value && is_nothrow_default_constructible<second_type>::value)
0138       : first(), second() {}
0139 
0140   template <bool _Dummy = true,
0141             __enable_if_t<_CheckArgsDep<_Dummy>::template __is_pair_constructible<_T1 const&, _T2 const&>(), int> = 0>
0142   _LIBCPP_HIDE_FROM_ABI
0143   _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_CheckArgsDep<_Dummy>::template __is_implicit<_T1 const&, _T2 const&>())
0144       pair(_T1 const& __t1, _T2 const& __t2) noexcept(is_nothrow_copy_constructible<first_type>::value &&
0145                                                       is_nothrow_copy_constructible<second_type>::value)
0146       : first(__t1), second(__t2) {}
0147 
0148   template <
0149 #  if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
0150       class _U1 = _T1,
0151       class _U2 = _T2,
0152 #  else
0153       class _U1,
0154       class _U2,
0155 #  endif
0156       __enable_if_t<_CheckArgs::template __is_pair_constructible<_U1, _U2>(), int> = 0 >
0157   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_CheckArgs::template __is_implicit<_U1, _U2>())
0158       pair(_U1&& __u1, _U2&& __u2) noexcept(is_nothrow_constructible<first_type, _U1>::value &&
0159                                             is_nothrow_constructible<second_type, _U2>::value)
0160       : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {
0161   }
0162 
0163 #  if _LIBCPP_STD_VER >= 23
0164   template <class _U1, class _U2, __enable_if_t<_CheckArgs::template __is_pair_constructible<_U1&, _U2&>(), int> = 0>
0165   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>())
0166       pair(pair<_U1, _U2>& __p) noexcept((is_nothrow_constructible<first_type, _U1&>::value &&
0167                                           is_nothrow_constructible<second_type, _U2&>::value))
0168       : first(__p.first), second(__p.second) {}
0169 #  endif
0170 
0171   template <class _U1,
0172             class _U2,
0173             __enable_if_t<_CheckArgs::template __is_pair_constructible<_U1 const&, _U2 const&>(), int> = 0>
0174   _LIBCPP_HIDE_FROM_ABI
0175   _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_CheckArgs::template __is_implicit<_U1 const&, _U2 const&>())
0176       pair(pair<_U1, _U2> const& __p) noexcept(is_nothrow_constructible<first_type, _U1 const&>::value &&
0177                                                is_nothrow_constructible<second_type, _U2 const&>::value)
0178       : first(__p.first), second(__p.second) {}
0179 
0180   template <class _U1, class _U2, __enable_if_t<_CheckArgs::template __is_pair_constructible<_U1, _U2>(), int> = 0>
0181   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!_CheckArgs::template __is_implicit<_U1, _U2>())
0182       pair(pair<_U1, _U2>&& __p) noexcept(is_nothrow_constructible<first_type, _U1&&>::value &&
0183                                           is_nothrow_constructible<second_type, _U2&&>::value)
0184       : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
0185 
0186 #  if _LIBCPP_STD_VER >= 23
0187   template <class _U1,
0188             class _U2,
0189             __enable_if_t<_CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>(), int> = 0>
0190   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_CheckArgs::template __is_implicit<const _U1&&, const _U2&&>())
0191       pair(const pair<_U1, _U2>&& __p) noexcept(is_nothrow_constructible<first_type, const _U1&&>::value &&
0192                                                 is_nothrow_constructible<second_type, const _U2&&>::value)
0193       : first(std::move(__p.first)), second(std::move(__p.second)) {}
0194 #  endif
0195 
0196 #  if _LIBCPP_STD_VER >= 23
0197   // TODO: Remove this workaround in LLVM 20. The bug got fixed in Clang 18.
0198   // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed.
0199   template <class _PairLike>
0200   _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() {
0201     if constexpr (__pair_like_no_subrange<_PairLike>) {
0202       return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> ||
0203              !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>;
0204     }
0205     return false;
0206   }
0207 
0208   template <__pair_like_no_subrange _PairLike>
0209     requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike &&>()))> &&
0210              is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike &&>()))>)
0211   _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>()) pair(_PairLike&& __p)
0212       : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {}
0213 #  endif
0214 
0215   template <class... _Args1, class... _Args2>
0216   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
0217   pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) noexcept(
0218       is_nothrow_constructible<first_type, _Args1...>::value && is_nothrow_constructible<second_type, _Args2...>::value)
0219       : pair(__pc,
0220              __first_args,
0221              __second_args,
0222              typename __make_tuple_indices<sizeof...(_Args1)>::type(),
0223              typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
0224 
0225   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair&
0226   operator=(__conditional_t<is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value,
0227                             pair,
0228                             __nat> const& __p) noexcept(is_nothrow_copy_assignable<first_type>::value &&
0229                                                         is_nothrow_copy_assignable<second_type>::value) {
0230     first  = __p.first;
0231     second = __p.second;
0232     return *this;
0233   }
0234 
0235   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(
0236       __conditional_t<is_move_assignable<first_type>::value && is_move_assignable<second_type>::value, pair, __nat>&&
0237           __p) noexcept(is_nothrow_move_assignable<first_type>::value &&
0238                         is_nothrow_move_assignable<second_type>::value) {
0239     first  = std::forward<first_type>(__p.first);
0240     second = std::forward<second_type>(__p.second);
0241     return *this;
0242   }
0243 
0244   template <
0245       class _U1,
0246       class _U2,
0247       __enable_if_t<is_assignable<first_type&, _U1 const&>::value && is_assignable<second_type&, _U2 const&>::value,
0248                     int> = 0>
0249   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2> const& __p) {
0250     first  = __p.first;
0251     second = __p.second;
0252     return *this;
0253   }
0254 
0255   template <class _U1,
0256             class _U2,
0257             __enable_if_t<is_assignable<first_type&, _U1>::value && is_assignable<second_type&, _U2>::value, int> = 0>
0258   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2>&& __p) {
0259     first  = std::forward<_U1>(__p.first);
0260     second = std::forward<_U2>(__p.second);
0261     return *this;
0262   }
0263 
0264 #  if _LIBCPP_STD_VER >= 23
0265   template <class = void>
0266   _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair const& __p) const
0267       noexcept(is_nothrow_copy_assignable_v<const first_type> && is_nothrow_copy_assignable_v<const second_type>)
0268     requires(is_copy_assignable_v<const first_type> && is_copy_assignable_v<const second_type>)
0269   {
0270     first  = __p.first;
0271     second = __p.second;
0272     return *this;
0273   }
0274 
0275   template <class = void>
0276   _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair&& __p) const
0277       noexcept(is_nothrow_assignable_v<const first_type&, first_type> &&
0278                is_nothrow_assignable_v<const second_type&, second_type>)
0279     requires(is_assignable_v<const first_type&, first_type> && is_assignable_v<const second_type&, second_type>)
0280   {
0281     first  = std::forward<first_type>(__p.first);
0282     second = std::forward<second_type>(__p.second);
0283     return *this;
0284   }
0285 
0286   template <class _U1, class _U2>
0287   _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(const pair<_U1, _U2>& __p) const
0288     requires(is_assignable_v<const first_type&, const _U1&> && is_assignable_v<const second_type&, const _U2&>)
0289   {
0290     first  = __p.first;
0291     second = __p.second;
0292     return *this;
0293   }
0294 
0295   template <class _U1, class _U2>
0296   _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair<_U1, _U2>&& __p) const
0297     requires(is_assignable_v<const first_type&, _U1> && is_assignable_v<const second_type&, _U2>)
0298   {
0299     first  = std::forward<_U1>(__p.first);
0300     second = std::forward<_U2>(__p.second);
0301     return *this;
0302   }
0303 
0304   template <__pair_like_no_subrange _PairLike>
0305     requires(__different_from<_PairLike, pair> &&
0306              is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
0307              is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>)
0308   _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) {
0309     first  = std::get<0>(std::forward<_PairLike>(__p));
0310     second = std::get<1>(std::forward<_PairLike>(__p));
0311     return *this;
0312   }
0313 
0314   template <__pair_like_no_subrange _PairLike>
0315     requires(__different_from<_PairLike, pair> &&
0316              is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
0317              is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>)
0318   _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const {
0319     first  = std::get<0>(std::forward<_PairLike>(__p));
0320     second = std::get<1>(std::forward<_PairLike>(__p));
0321     return *this;
0322   }
0323 #  endif // _LIBCPP_STD_VER >= 23
0324 
0325   // Prior to C++23, we provide an approximation of constructors and assignment operators from
0326   // pair-like types. This was historically provided as an extension.
0327 #  if _LIBCPP_STD_VER < 23
0328   // from std::tuple
0329   template <class _U1,
0330             class _U2,
0331             __enable_if_t<is_convertible<_U1 const&, _T1>::value && is_convertible<_U2 const&, _T2>::value, int> = 0>
0332   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(tuple<_U1, _U2> const& __p)
0333       : first(std::get<0>(__p)), second(std::get<1>(__p)) {}
0334 
0335   template < class _U1,
0336              class _U2,
0337              __enable_if_t<is_constructible<_T1, _U1 const&>::value && is_constructible<_T2, _U2 const&>::value &&
0338                                !(is_convertible<_U1 const&, _T1>::value && is_convertible<_U2 const&, _T2>::value),
0339                            int> = 0>
0340   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(tuple<_U1, _U2> const& __p)
0341       : first(std::get<0>(__p)), second(std::get<1>(__p)) {}
0342 
0343   template <class _U1,
0344             class _U2,
0345             __enable_if_t<is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value, int> = 0>
0346   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(tuple<_U1, _U2>&& __p)
0347       : first(std::get<0>(std::move(__p))), second(std::get<1>(std::move(__p))) {}
0348 
0349   template <class _U1,
0350             class _U2,
0351             __enable_if_t<is_constructible<_T1, _U1>::value && is_constructible<_T2, _U2>::value &&
0352                           !(is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value) > = 0>
0353   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(tuple<_U1, _U2>&& __p)
0354       : first(std::get<0>(std::move(__p))), second(std::get<1>(std::move(__p))) {}
0355 
0356   template <class _U1,
0357             class _U2,
0358             __enable_if_t<is_assignable<_T1&, _U1 const&>::value && is_assignable<_T2&, _U2 const&>::value, int> = 0>
0359   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2> const& __p) {
0360     first  = std::get<0>(__p);
0361     second = std::get<1>(__p);
0362     return *this;
0363   }
0364 
0365   template <class _U1,
0366             class _U2,
0367             __enable_if_t<is_assignable<_T1&, _U1&&>::value && is_assignable<_T2&, _U2&&>::value, int> = 0>
0368   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2>&& __p) {
0369     first  = std::get<0>(std::move(__p));
0370     second = std::get<1>(std::move(__p));
0371     return *this;
0372   }
0373 
0374   // from std::array
0375   template <class _Up,
0376             __enable_if_t<is_convertible<_Up const&, _T1>::value && is_convertible<_Up const&, _T2>::value, int> = 0>
0377   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(array<_Up, 2> const& __p) : first(__p[0]), second(__p[1]) {}
0378 
0379   template <class _Up,
0380             __enable_if_t<is_constructible<_T1, _Up const&>::value && is_constructible<_T2, _Up const&>::value &&
0381                               !(is_convertible<_Up const&, _T1>::value && is_convertible<_Up const&, _T2>::value),
0382                           int> = 0>
0383   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(array<_Up, 2> const& __p)
0384       : first(__p[0]), second(__p[1]) {}
0385 
0386   template <class _Up, __enable_if_t< is_convertible<_Up, _T1>::value && is_convertible<_Up, _T2>::value, int> = 0>
0387   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(array<_Up, 2>&& __p)
0388       : first(std::move(__p)[0]), second(std::move(__p)[1]) {}
0389 
0390   template <class _Up,
0391             __enable_if_t<is_constructible<_T1, _Up>::value && is_constructible<_T2, _Up>::value &&
0392                               !(is_convertible<_Up, _T1>::value && is_convertible<_Up, _T2>::value),
0393                           int> = 0>
0394   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(array<_Up, 2>&& __p)
0395       : first(std::move(__p)[0]), second(std::move(__p)[1]) {}
0396 
0397   template <class _Up,
0398             __enable_if_t<is_assignable<_T1&, _Up const&>::value && is_assignable<_T2&, _Up const&>::value, int> = 0>
0399   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2> const& __p) {
0400     first  = std::get<0>(__p);
0401     second = std::get<1>(__p);
0402     return *this;
0403   }
0404 
0405   template <class _Up, __enable_if_t<is_assignable<_T1&, _Up>::value && is_assignable<_T2&, _Up>::value, int> = 0>
0406   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2>&& __p) {
0407     first  = std::get<0>(std::move(__p));
0408     second = std::get<1>(std::move(__p));
0409     return *this;
0410   }
0411 #  endif // _LIBCPP_STD_VER < 23
0412 #endif   // _LIBCPP_CXX03_LANG
0413 
0414   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(pair& __p)
0415       _NOEXCEPT_(__is_nothrow_swappable_v<first_type>&& __is_nothrow_swappable_v<second_type>) {
0416     using std::swap;
0417     swap(first, __p.first);
0418     swap(second, __p.second);
0419   }
0420 
0421 #if _LIBCPP_STD_VER >= 23
0422   _LIBCPP_HIDE_FROM_ABI constexpr void swap(const pair& __p) const
0423       noexcept(__is_nothrow_swappable_v<const first_type> && __is_nothrow_swappable_v<const second_type>) {
0424     using std::swap;
0425     swap(first, __p.first);
0426     swap(second, __p.second);
0427   }
0428 #endif
0429 
0430 private:
0431 #ifndef _LIBCPP_CXX03_LANG
0432   template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
0433   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
0434   pair(piecewise_construct_t,
0435        tuple<_Args1...>& __first_args,
0436        tuple<_Args2...>& __second_args,
0437        __tuple_indices<_I1...>,
0438        __tuple_indices<_I2...>)
0439       : first(std::forward<_Args1>(std::get<_I1>(__first_args))...),
0440         second(std::forward<_Args2>(std::get<_I2>(__second_args))...) {}
0441 #endif
0442 };
0443 
0444 #if _LIBCPP_STD_VER >= 17
0445 template <class _T1, class _T2>
0446 pair(_T1, _T2) -> pair<_T1, _T2>;
0447 #endif
0448 
0449 // [pairs.spec], specialized algorithms
0450 
0451 template <class _T1, class _T2, class _U1, class _U2>
0452 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
0453 operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
0454   return __x.first == __y.first && __x.second == __y.second;
0455 }
0456 
0457 #if _LIBCPP_STD_VER >= 20
0458 
0459 template <class _T1, class _T2, class _U1, class _U2>
0460 _LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t< __synth_three_way_result<_T1, _U1>,
0461                                                               __synth_three_way_result<_T2, _U2> >
0462 operator<=>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
0463   if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) {
0464     return __c;
0465   }
0466   return std::__synth_three_way(__x.second, __y.second);
0467 }
0468 
0469 #else // _LIBCPP_STD_VER >= 20
0470 
0471 template <class _T1, class _T2, class _U1, class _U2>
0472 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
0473 operator!=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
0474   return !(__x == __y);
0475 }
0476 
0477 template <class _T1, class _T2, class _U1, class _U2>
0478 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
0479 operator<(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
0480   return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
0481 }
0482 
0483 template <class _T1, class _T2, class _U1, class _U2>
0484 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
0485 operator>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
0486   return __y < __x;
0487 }
0488 
0489 template <class _T1, class _T2, class _U1, class _U2>
0490 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
0491 operator>=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
0492   return !(__x < __y);
0493 }
0494 
0495 template <class _T1, class _T2, class _U1, class _U2>
0496 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
0497 operator<=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
0498   return !(__y < __x);
0499 }
0500 
0501 #endif // _LIBCPP_STD_VER >= 20
0502 
0503 #if _LIBCPP_STD_VER >= 23
0504 template <class _T1, class _T2, class _U1, class _U2, template <class> class _TQual, template <class> class _UQual>
0505   requires requires {
0506     typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
0507   }
0508 struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> {
0509   using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
0510 };
0511 
0512 template <class _T1, class _T2, class _U1, class _U2>
0513   requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
0514 struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> {
0515   using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>;
0516 };
0517 #endif // _LIBCPP_STD_VER >= 23
0518 
0519 template <class _T1, class _T2, __enable_if_t<__is_swappable_v<_T1> && __is_swappable_v<_T2>, int> = 0>
0520 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
0521     _NOEXCEPT_(__is_nothrow_swappable_v<_T1>&& __is_nothrow_swappable_v<_T2>) {
0522   __x.swap(__y);
0523 }
0524 
0525 #if _LIBCPP_STD_VER >= 23
0526 template <class _T1, class _T2>
0527   requires(__is_swappable_v<const _T1> && __is_swappable_v<const _T2>)
0528 _LIBCPP_HIDE_FROM_ABI constexpr void
0529 swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x.swap(__y))) {
0530   __x.swap(__y);
0531 }
0532 #endif
0533 
0534 template <class _T1, class _T2>
0535 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<__unwrap_ref_decay_t<_T1>, __unwrap_ref_decay_t<_T2> >
0536 make_pair(_T1&& __t1, _T2&& __t2) {
0537   return pair<__unwrap_ref_decay_t<_T1>, __unwrap_ref_decay_t<_T2> >(std::forward<_T1>(__t1), std::forward<_T2>(__t2));
0538 }
0539 
0540 template <class _T1, class _T2>
0541 struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > : public integral_constant<size_t, 2> {};
0542 
0543 template <size_t _Ip, class _T1, class _T2>
0544 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> > {
0545   static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
0546 };
0547 
0548 template <class _T1, class _T2>
0549 struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > {
0550   using type _LIBCPP_NODEBUG = _T1;
0551 };
0552 
0553 template <class _T1, class _T2>
0554 struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > {
0555   using type _LIBCPP_NODEBUG = _T2;
0556 };
0557 
0558 template <size_t _Ip>
0559 struct __get_pair;
0560 
0561 template <>
0562 struct __get_pair<0> {
0563   template <class _T1, class _T2>
0564   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
0565     return __p.first;
0566   }
0567 
0568   template <class _T1, class _T2>
0569   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T1& get(const pair<_T1, _T2>& __p) _NOEXCEPT {
0570     return __p.first;
0571   }
0572 
0573   template <class _T1, class _T2>
0574   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
0575     return std::forward<_T1>(__p.first);
0576   }
0577 
0578   template <class _T1, class _T2>
0579   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T1&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
0580     return std::forward<const _T1>(__p.first);
0581   }
0582 };
0583 
0584 template <>
0585 struct __get_pair<1> {
0586   template <class _T1, class _T2>
0587   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT {
0588     return __p.second;
0589   }
0590 
0591   template <class _T1, class _T2>
0592   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T2& get(const pair<_T1, _T2>& __p) _NOEXCEPT {
0593     return __p.second;
0594   }
0595 
0596   template <class _T1, class _T2>
0597   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
0598     return std::forward<_T2>(__p.second);
0599   }
0600 
0601   template <class _T1, class _T2>
0602   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T2&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
0603     return std::forward<const _T2>(__p.second);
0604   }
0605 };
0606 
0607 template <size_t _Ip, class _T1, class _T2>
0608 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
0609 get(pair<_T1, _T2>& __p) _NOEXCEPT {
0610   return __get_pair<_Ip>::get(__p);
0611 }
0612 
0613 template <size_t _Ip, class _T1, class _T2>
0614 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
0615 get(const pair<_T1, _T2>& __p) _NOEXCEPT {
0616   return __get_pair<_Ip>::get(__p);
0617 }
0618 
0619 template <size_t _Ip, class _T1, class _T2>
0620 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
0621 get(pair<_T1, _T2>&& __p) _NOEXCEPT {
0622   return __get_pair<_Ip>::get(std::move(__p));
0623 }
0624 
0625 template <size_t _Ip, class _T1, class _T2>
0626 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
0627 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
0628   return __get_pair<_Ip>::get(std::move(__p));
0629 }
0630 
0631 #if _LIBCPP_STD_VER >= 14
0632 template <class _T1, class _T2>
0633 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
0634   return __get_pair<0>::get(__p);
0635 }
0636 
0637 template <class _T1, class _T2>
0638 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
0639   return __get_pair<0>::get(__p);
0640 }
0641 
0642 template <class _T1, class _T2>
0643 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
0644   return __get_pair<0>::get(std::move(__p));
0645 }
0646 
0647 template <class _T1, class _T2>
0648 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT {
0649   return __get_pair<0>::get(std::move(__p));
0650 }
0651 
0652 template <class _T1, class _T2>
0653 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T2, _T1>& __p) _NOEXCEPT {
0654   return __get_pair<1>::get(__p);
0655 }
0656 
0657 template <class _T1, class _T2>
0658 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T2, _T1> const& __p) _NOEXCEPT {
0659   return __get_pair<1>::get(__p);
0660 }
0661 
0662 template <class _T1, class _T2>
0663 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T2, _T1>&& __p) _NOEXCEPT {
0664   return __get_pair<1>::get(std::move(__p));
0665 }
0666 
0667 template <class _T1, class _T2>
0668 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T2, _T1> const&& __p) _NOEXCEPT {
0669   return __get_pair<1>::get(std::move(__p));
0670 }
0671 
0672 #endif // _LIBCPP_STD_VER >= 14
0673 
0674 _LIBCPP_END_NAMESPACE_STD
0675 
0676 _LIBCPP_POP_MACROS
0677 
0678 #endif // _LIBCPP___UTILITY_PAIR_H