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