xref: /freebsd/contrib/llvm-project/libcxx/include/__utility/pair.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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