xref: /freebsd/contrib/llvm-project/libcxx/include/__utility/pair.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric 
9fe6060f1SDimitry Andric #ifndef _LIBCPP___UTILITY_PAIR_H
10fe6060f1SDimitry Andric #define _LIBCPP___UTILITY_PAIR_H
11fe6060f1SDimitry Andric 
12349cc55cSDimitry Andric #include <__compare/common_comparison_category.h>
13349cc55cSDimitry Andric #include <__compare/synth_three_way.h>
14*06c3fb27SDimitry Andric #include <__concepts/different_from.h>
15fe6060f1SDimitry Andric #include <__config>
16*06c3fb27SDimitry Andric #include <__fwd/array.h>
17bdd1243dSDimitry Andric #include <__fwd/get.h>
18*06c3fb27SDimitry Andric #include <__fwd/pair.h>
19*06c3fb27SDimitry Andric #include <__fwd/subrange.h>
20bdd1243dSDimitry Andric #include <__fwd/tuple.h>
21*06c3fb27SDimitry Andric #include <__tuple/pair_like.h>
22*06c3fb27SDimitry Andric #include <__tuple/sfinae_helpers.h>
23*06c3fb27SDimitry Andric #include <__tuple/tuple_element.h>
24*06c3fb27SDimitry Andric #include <__tuple/tuple_indices.h>
25*06c3fb27SDimitry Andric #include <__tuple/tuple_size.h>
26bdd1243dSDimitry Andric #include <__type_traits/common_reference.h>
27bdd1243dSDimitry Andric #include <__type_traits/common_type.h>
28bdd1243dSDimitry Andric #include <__type_traits/conditional.h>
29*06c3fb27SDimitry Andric #include <__type_traits/decay.h>
30*06c3fb27SDimitry Andric #include <__type_traits/integral_constant.h>
31bdd1243dSDimitry Andric #include <__type_traits/is_assignable.h>
32bdd1243dSDimitry Andric #include <__type_traits/is_constructible.h>
33bdd1243dSDimitry Andric #include <__type_traits/is_convertible.h>
34bdd1243dSDimitry Andric #include <__type_traits/is_copy_assignable.h>
35bdd1243dSDimitry Andric #include <__type_traits/is_default_constructible.h>
36bdd1243dSDimitry Andric #include <__type_traits/is_implicitly_default_constructible.h>
37bdd1243dSDimitry Andric #include <__type_traits/is_move_assignable.h>
38bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_assignable.h>
39bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_constructible.h>
40bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_copy_assignable.h>
41bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_copy_constructible.h>
42bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_default_constructible.h>
43bdd1243dSDimitry Andric #include <__type_traits/is_nothrow_move_assignable.h>
44bdd1243dSDimitry Andric #include <__type_traits/is_same.h>
45bdd1243dSDimitry Andric #include <__type_traits/is_swappable.h>
46bdd1243dSDimitry Andric #include <__type_traits/nat.h>
47*06c3fb27SDimitry Andric #include <__type_traits/remove_cvref.h>
48*06c3fb27SDimitry Andric #include <__type_traits/unwrap_ref.h>
49*06c3fb27SDimitry Andric #include <__utility/declval.h>
50fe6060f1SDimitry Andric #include <__utility/forward.h>
51fe6060f1SDimitry Andric #include <__utility/move.h>
52fe6060f1SDimitry Andric #include <__utility/piecewise_construct.h>
53fe6060f1SDimitry Andric #include <cstddef>
54fe6060f1SDimitry Andric 
55fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
56fe6060f1SDimitry Andric #  pragma GCC system_header
57fe6060f1SDimitry Andric #endif
58fe6060f1SDimitry Andric 
59*06c3fb27SDimitry Andric _LIBCPP_PUSH_MACROS
60*06c3fb27SDimitry Andric #include <__undef_macros>
61*06c3fb27SDimitry Andric 
62fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
63fe6060f1SDimitry Andric 
64fe6060f1SDimitry Andric template <class, class>
65fe6060f1SDimitry Andric struct __non_trivially_copyable_base {
66*06c3fb27SDimitry Andric   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
67fe6060f1SDimitry Andric   __non_trivially_copyable_base() _NOEXCEPT {}
68*06c3fb27SDimitry Andric   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
69fe6060f1SDimitry Andric   __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
70fe6060f1SDimitry Andric };
71*06c3fb27SDimitry Andric 
72*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23
73*06c3fb27SDimitry Andric template <class _Tp>
74*06c3fb27SDimitry Andric struct __is_specialization_of_subrange : false_type {};
75*06c3fb27SDimitry Andric 
76*06c3fb27SDimitry Andric template <class _Iter, class _Sent, ranges::subrange_kind _Kind>
77*06c3fb27SDimitry Andric struct __is_specialization_of_subrange<ranges::subrange<_Iter, _Sent, _Kind>> : true_type {};
78fe6060f1SDimitry Andric #endif
79fe6060f1SDimitry Andric 
80fe6060f1SDimitry Andric template <class _T1, class _T2>
81fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS pair
82fe6060f1SDimitry Andric #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
83fe6060f1SDimitry Andric : private __non_trivially_copyable_base<_T1, _T2>
84fe6060f1SDimitry Andric #endif
85fe6060f1SDimitry Andric {
86*06c3fb27SDimitry Andric     using first_type = _T1;
87*06c3fb27SDimitry Andric     using second_type = _T2;
88fe6060f1SDimitry Andric 
89fe6060f1SDimitry Andric     _T1 first;
90fe6060f1SDimitry Andric     _T2 second;
91fe6060f1SDimitry Andric 
92*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
93*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;
94fe6060f1SDimitry Andric 
95fe6060f1SDimitry Andric #ifdef _LIBCPP_CXX03_LANG
96*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI
97fe6060f1SDimitry Andric     pair() : first(), second() {}
98fe6060f1SDimitry Andric 
99*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI
100fe6060f1SDimitry Andric     pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
101fe6060f1SDimitry Andric 
102fe6060f1SDimitry Andric     template <class _U1, class _U2>
103*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI
104fe6060f1SDimitry Andric     pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
105fe6060f1SDimitry Andric 
106*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI
107fe6060f1SDimitry Andric     pair& operator=(pair const& __p) {
108fe6060f1SDimitry Andric         first = __p.first;
109fe6060f1SDimitry Andric         second = __p.second;
110fe6060f1SDimitry Andric         return *this;
111fe6060f1SDimitry Andric     }
112*06c3fb27SDimitry Andric 
113*06c3fb27SDimitry Andric     // Extension: This is provided in C++03 because it allows properly handling the
114*06c3fb27SDimitry Andric     //            assignment to a pair containing references, which would be a hard
115*06c3fb27SDimitry Andric     //            error otherwise.
116*06c3fb27SDimitry Andric     template <class _U1, class _U2, class = __enable_if_t<
117*06c3fb27SDimitry Andric         is_assignable<first_type&, _U1 const&>::value &&
118*06c3fb27SDimitry Andric         is_assignable<second_type&, _U2 const&>::value
119*06c3fb27SDimitry Andric     > >
120*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI
121*06c3fb27SDimitry Andric     pair& operator=(pair<_U1, _U2> const& __p) {
122*06c3fb27SDimitry Andric         first = __p.first;
123*06c3fb27SDimitry Andric         second = __p.second;
124*06c3fb27SDimitry Andric         return *this;
125*06c3fb27SDimitry Andric     }
126fe6060f1SDimitry Andric #else
127fe6060f1SDimitry Andric     struct _CheckArgs {
128fe6060f1SDimitry Andric       template <int&...>
129*06c3fb27SDimitry Andric       static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() {
130fe6060f1SDimitry Andric           return is_default_constructible<_T1>::value
131fe6060f1SDimitry Andric               && is_default_constructible<_T2>::value
132fe6060f1SDimitry Andric               && !__enable_implicit_default<>();
133fe6060f1SDimitry Andric       }
134fe6060f1SDimitry Andric 
135fe6060f1SDimitry Andric       template <int&...>
136*06c3fb27SDimitry Andric       static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() {
137fe6060f1SDimitry Andric           return __is_implicitly_default_constructible<_T1>::value
138fe6060f1SDimitry Andric               && __is_implicitly_default_constructible<_T2>::value;
139fe6060f1SDimitry Andric       }
140fe6060f1SDimitry Andric 
141fe6060f1SDimitry Andric       template <class _U1, class _U2>
142*06c3fb27SDimitry Andric       static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() {
143fe6060f1SDimitry Andric           return is_constructible<first_type, _U1>::value
144bdd1243dSDimitry Andric               && is_constructible<second_type, _U2>::value;
145bdd1243dSDimitry Andric       }
146bdd1243dSDimitry Andric 
147bdd1243dSDimitry Andric       template <class _U1, class _U2>
148*06c3fb27SDimitry Andric       static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() {
149bdd1243dSDimitry Andric           return is_convertible<_U1, first_type>::value
150bdd1243dSDimitry Andric               && is_convertible<_U2, second_type>::value;
151bdd1243dSDimitry Andric       }
152bdd1243dSDimitry Andric 
153bdd1243dSDimitry Andric       template <class _U1, class _U2>
154*06c3fb27SDimitry Andric       static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() {
155bdd1243dSDimitry Andric           return __is_pair_constructible<_U1, _U2>() && !__is_implicit<_U1, _U2>();
156fe6060f1SDimitry Andric       }
157fe6060f1SDimitry Andric 
158fe6060f1SDimitry Andric       template <class _U1, class _U2>
159*06c3fb27SDimitry Andric       static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() {
160bdd1243dSDimitry Andric           return __is_pair_constructible<_U1, _U2>() && __is_implicit<_U1, _U2>();
161fe6060f1SDimitry Andric       }
162fe6060f1SDimitry Andric     };
163fe6060f1SDimitry Andric 
164fe6060f1SDimitry Andric     template <bool _MaybeEnable>
165349cc55cSDimitry Andric     using _CheckArgsDep _LIBCPP_NODEBUG = typename conditional<
166fe6060f1SDimitry Andric       _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
167fe6060f1SDimitry Andric 
168349cc55cSDimitry Andric     template<bool _Dummy = true, typename enable_if<
169fe6060f1SDimitry Andric             _CheckArgsDep<_Dummy>::__enable_explicit_default()
170349cc55cSDimitry Andric     >::type* = nullptr>
171*06c3fb27SDimitry Andric     explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
172fe6060f1SDimitry Andric     pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
173fe6060f1SDimitry Andric                       is_nothrow_default_constructible<second_type>::value)
174fe6060f1SDimitry Andric         : first(), second() {}
175fe6060f1SDimitry Andric 
176349cc55cSDimitry Andric     template<bool _Dummy = true, typename enable_if<
177fe6060f1SDimitry Andric             _CheckArgsDep<_Dummy>::__enable_implicit_default()
178349cc55cSDimitry Andric     >::type* = nullptr>
179*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
180fe6060f1SDimitry Andric     pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
181fe6060f1SDimitry Andric                       is_nothrow_default_constructible<second_type>::value)
182fe6060f1SDimitry Andric         : first(), second() {}
183fe6060f1SDimitry Andric 
184349cc55cSDimitry Andric     template <bool _Dummy = true, typename enable_if<
185fe6060f1SDimitry Andric              _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>()
186349cc55cSDimitry Andric     >::type* = nullptr>
187*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
188fe6060f1SDimitry Andric     explicit pair(_T1 const& __t1, _T2 const& __t2)
189fe6060f1SDimitry Andric         _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
190fe6060f1SDimitry Andric                    is_nothrow_copy_constructible<second_type>::value)
191fe6060f1SDimitry Andric         : first(__t1), second(__t2) {}
192fe6060f1SDimitry Andric 
193349cc55cSDimitry Andric     template<bool _Dummy = true, typename enable_if<
194fe6060f1SDimitry Andric             _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>()
195349cc55cSDimitry Andric     >::type* = nullptr>
196*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
197fe6060f1SDimitry Andric     pair(_T1 const& __t1, _T2 const& __t2)
198fe6060f1SDimitry Andric         _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
199fe6060f1SDimitry Andric                    is_nothrow_copy_constructible<second_type>::value)
200fe6060f1SDimitry Andric         : first(__t1), second(__t2) {}
201fe6060f1SDimitry Andric 
202349cc55cSDimitry Andric     template <
203*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
204349cc55cSDimitry Andric         class _U1 = _T1, class _U2 = _T2,
205349cc55cSDimitry Andric #else
206349cc55cSDimitry Andric         class _U1, class _U2,
207349cc55cSDimitry Andric #endif
208349cc55cSDimitry Andric         typename enable_if<_CheckArgs::template __enable_explicit<_U1, _U2>()>::type* = nullptr
209349cc55cSDimitry Andric     >
210*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
211fe6060f1SDimitry Andric     explicit pair(_U1&& __u1, _U2&& __u2)
212fe6060f1SDimitry Andric         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
213fe6060f1SDimitry Andric                     is_nothrow_constructible<second_type, _U2>::value))
214*06c3fb27SDimitry Andric         : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {}
215fe6060f1SDimitry Andric 
216349cc55cSDimitry Andric     template <
217*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
218349cc55cSDimitry Andric         class _U1 = _T1, class _U2 = _T2,
219349cc55cSDimitry Andric #else
220349cc55cSDimitry Andric         class _U1, class _U2,
221349cc55cSDimitry Andric #endif
222349cc55cSDimitry Andric         typename enable_if<_CheckArgs::template __enable_implicit<_U1, _U2>()>::type* = nullptr
223349cc55cSDimitry Andric     >
224*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
225fe6060f1SDimitry Andric     pair(_U1&& __u1, _U2&& __u2)
226fe6060f1SDimitry Andric         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
227fe6060f1SDimitry Andric                     is_nothrow_constructible<second_type, _U2>::value))
228*06c3fb27SDimitry Andric         : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {}
229fe6060f1SDimitry Andric 
230*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23
231bdd1243dSDimitry Andric     template<class _U1, class _U2, __enable_if_t<
232bdd1243dSDimitry Andric             _CheckArgs::template __is_pair_constructible<_U1&, _U2&>()
233bdd1243dSDimitry Andric     >* = nullptr>
234bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr
235bdd1243dSDimitry Andric     explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>()) pair(pair<_U1, _U2>& __p)
236bdd1243dSDimitry Andric         noexcept((is_nothrow_constructible<first_type, _U1&>::value &&
237bdd1243dSDimitry Andric                   is_nothrow_constructible<second_type, _U2&>::value))
238bdd1243dSDimitry Andric         : first(__p.first), second(__p.second) {}
239bdd1243dSDimitry Andric #endif
240bdd1243dSDimitry Andric 
241349cc55cSDimitry Andric     template<class _U1, class _U2, typename enable_if<
242fe6060f1SDimitry Andric             _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>()
243349cc55cSDimitry Andric     >::type* = nullptr>
244*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
245fe6060f1SDimitry Andric     explicit pair(pair<_U1, _U2> const& __p)
246fe6060f1SDimitry Andric         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
247fe6060f1SDimitry Andric                     is_nothrow_constructible<second_type, _U2 const&>::value))
248fe6060f1SDimitry Andric         : first(__p.first), second(__p.second) {}
249fe6060f1SDimitry Andric 
250349cc55cSDimitry Andric     template<class _U1, class _U2, typename enable_if<
251fe6060f1SDimitry Andric             _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>()
252349cc55cSDimitry Andric     >::type* = nullptr>
253*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
254fe6060f1SDimitry Andric     pair(pair<_U1, _U2> const& __p)
255fe6060f1SDimitry Andric         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
256fe6060f1SDimitry Andric                     is_nothrow_constructible<second_type, _U2 const&>::value))
257fe6060f1SDimitry Andric         : first(__p.first), second(__p.second) {}
258fe6060f1SDimitry Andric 
259349cc55cSDimitry Andric     template<class _U1, class _U2, typename enable_if<
260fe6060f1SDimitry Andric             _CheckArgs::template __enable_explicit<_U1, _U2>()
261349cc55cSDimitry Andric     >::type* = nullptr>
262*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
263fe6060f1SDimitry Andric     explicit pair(pair<_U1, _U2>&&__p)
264fe6060f1SDimitry Andric         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
265fe6060f1SDimitry Andric                     is_nothrow_constructible<second_type, _U2&&>::value))
266*06c3fb27SDimitry Andric         : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
267fe6060f1SDimitry Andric 
268349cc55cSDimitry Andric     template<class _U1, class _U2, typename enable_if<
269fe6060f1SDimitry Andric             _CheckArgs::template __enable_implicit<_U1, _U2>()
270349cc55cSDimitry Andric     >::type* = nullptr>
271*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
272fe6060f1SDimitry Andric     pair(pair<_U1, _U2>&& __p)
273fe6060f1SDimitry Andric         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
274fe6060f1SDimitry Andric                     is_nothrow_constructible<second_type, _U2&&>::value))
275*06c3fb27SDimitry Andric         : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
276fe6060f1SDimitry Andric 
277*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23
278bdd1243dSDimitry Andric     template<class _U1, class _U2, __enable_if_t<
279bdd1243dSDimitry Andric             _CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>()
280bdd1243dSDimitry Andric     >* = nullptr>
281bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr
282bdd1243dSDimitry Andric     explicit(!_CheckArgs::template __is_implicit<const _U1&&, const _U2&&>())
283bdd1243dSDimitry Andric     pair(const pair<_U1, _U2>&& __p)
284bdd1243dSDimitry Andric         noexcept(is_nothrow_constructible<first_type, const _U1&&>::value &&
285bdd1243dSDimitry Andric                  is_nothrow_constructible<second_type, const _U2&&>::value)
286bdd1243dSDimitry Andric         : first(std::move(__p.first)), second(std::move(__p.second)) {}
287bdd1243dSDimitry Andric #endif
288bdd1243dSDimitry Andric 
289*06c3fb27SDimitry Andric #  if _LIBCPP_STD_VER >= 23
290*06c3fb27SDimitry Andric     // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed.
291*06c3fb27SDimitry Andric     template <class _PairLike, bool _Enable = tuple_size<remove_cvref_t<_PairLike>>::value == 2>
292*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() {
293*06c3fb27SDimitry Andric         if constexpr (tuple_size<remove_cvref_t<_PairLike>>::value == 2) {
294*06c3fb27SDimitry Andric             return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> ||
295*06c3fb27SDimitry Andric                    !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>;
296*06c3fb27SDimitry Andric         }
297*06c3fb27SDimitry Andric         return false;
298*06c3fb27SDimitry Andric     }
299fe6060f1SDimitry Andric 
300*06c3fb27SDimitry Andric     template <__pair_like _PairLike>
301*06c3fb27SDimitry Andric       requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike&&>()))> &&
302*06c3fb27SDimitry Andric                is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike&&>()))>)
303*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>())
304*06c3fb27SDimitry Andric         pair(_PairLike&& __p)
305*06c3fb27SDimitry Andric         : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {}
306*06c3fb27SDimitry Andric #  endif
307fe6060f1SDimitry Andric 
308fe6060f1SDimitry Andric     template <class... _Args1, class... _Args2>
309*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
310fe6060f1SDimitry Andric     pair(piecewise_construct_t __pc,
311fe6060f1SDimitry Andric          tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
312fe6060f1SDimitry Andric         _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
313fe6060f1SDimitry Andric                     is_nothrow_constructible<second_type, _Args2...>::value))
314fe6060f1SDimitry Andric         : pair(__pc, __first_args, __second_args,
315fe6060f1SDimitry Andric                 typename __make_tuple_indices<sizeof...(_Args1)>::type(),
316fe6060f1SDimitry Andric                 typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
317fe6060f1SDimitry Andric 
318*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
319bdd1243dSDimitry Andric     pair& operator=(__conditional_t<
320fe6060f1SDimitry Andric                         is_copy_assignable<first_type>::value &&
321fe6060f1SDimitry Andric                         is_copy_assignable<second_type>::value,
322bdd1243dSDimitry Andric                     pair, __nat> const& __p)
323fe6060f1SDimitry Andric         _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
324fe6060f1SDimitry Andric                    is_nothrow_copy_assignable<second_type>::value)
325fe6060f1SDimitry Andric     {
326fe6060f1SDimitry Andric         first = __p.first;
327fe6060f1SDimitry Andric         second = __p.second;
328fe6060f1SDimitry Andric         return *this;
329fe6060f1SDimitry Andric     }
330fe6060f1SDimitry Andric 
331*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
332bdd1243dSDimitry Andric     pair& operator=(__conditional_t<
333fe6060f1SDimitry Andric                         is_move_assignable<first_type>::value &&
334fe6060f1SDimitry Andric                         is_move_assignable<second_type>::value,
335bdd1243dSDimitry Andric                     pair, __nat>&& __p)
336fe6060f1SDimitry Andric         _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
337fe6060f1SDimitry Andric                    is_nothrow_move_assignable<second_type>::value)
338fe6060f1SDimitry Andric     {
339*06c3fb27SDimitry Andric         first = std::forward<first_type>(__p.first);
340*06c3fb27SDimitry Andric         second = std::forward<second_type>(__p.second);
341fe6060f1SDimitry Andric         return *this;
342fe6060f1SDimitry Andric     }
343fe6060f1SDimitry Andric 
344*06c3fb27SDimitry Andric     template <class _U1, class _U2, __enable_if_t<
345*06c3fb27SDimitry Andric         is_assignable<first_type&, _U1 const&>::value &&
346*06c3fb27SDimitry Andric         is_assignable<second_type&, _U2 const&>::value
347*06c3fb27SDimitry Andric     >* = nullptr>
348*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
349*06c3fb27SDimitry Andric     pair& operator=(pair<_U1, _U2> const& __p) {
350*06c3fb27SDimitry Andric         first = __p.first;
351*06c3fb27SDimitry Andric         second = __p.second;
352*06c3fb27SDimitry Andric         return *this;
353*06c3fb27SDimitry Andric     }
354*06c3fb27SDimitry Andric 
355*06c3fb27SDimitry Andric     template <class _U1, class _U2, __enable_if_t<
356*06c3fb27SDimitry Andric         is_assignable<first_type&, _U1>::value &&
357*06c3fb27SDimitry Andric         is_assignable<second_type&, _U2>::value
358*06c3fb27SDimitry Andric     >* = nullptr>
359*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
360*06c3fb27SDimitry Andric     pair& operator=(pair<_U1, _U2>&& __p) {
361*06c3fb27SDimitry Andric         first = std::forward<_U1>(__p.first);
362*06c3fb27SDimitry Andric         second = std::forward<_U2>(__p.second);
363*06c3fb27SDimitry Andric         return *this;
364*06c3fb27SDimitry Andric     }
365*06c3fb27SDimitry Andric 
366*06c3fb27SDimitry Andric #  if _LIBCPP_STD_VER >= 23
367bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr
368bdd1243dSDimitry Andric     const pair& operator=(pair const& __p) const
369bdd1243dSDimitry Andric       noexcept(is_nothrow_copy_assignable_v<const first_type> &&
370bdd1243dSDimitry Andric                is_nothrow_copy_assignable_v<const second_type>)
371bdd1243dSDimitry Andric       requires(is_copy_assignable_v<const first_type> &&
372bdd1243dSDimitry Andric                is_copy_assignable_v<const second_type>) {
373bdd1243dSDimitry Andric         first = __p.first;
374bdd1243dSDimitry Andric         second = __p.second;
375bdd1243dSDimitry Andric         return *this;
376bdd1243dSDimitry Andric     }
377bdd1243dSDimitry Andric 
378bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr
379bdd1243dSDimitry Andric     const pair& operator=(pair&& __p) const
380bdd1243dSDimitry Andric       noexcept(is_nothrow_assignable_v<const first_type&, first_type> &&
381bdd1243dSDimitry Andric                is_nothrow_assignable_v<const second_type&, second_type>)
382bdd1243dSDimitry Andric       requires(is_assignable_v<const first_type&, first_type> &&
383bdd1243dSDimitry Andric                is_assignable_v<const second_type&, second_type>) {
384bdd1243dSDimitry Andric         first = std::forward<first_type>(__p.first);
385bdd1243dSDimitry Andric         second = std::forward<second_type>(__p.second);
386bdd1243dSDimitry Andric         return *this;
387bdd1243dSDimitry Andric     }
388bdd1243dSDimitry Andric 
389bdd1243dSDimitry Andric     template<class _U1, class _U2>
390bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr
391bdd1243dSDimitry Andric     const pair& operator=(const pair<_U1, _U2>& __p) const
392bdd1243dSDimitry Andric       requires(is_assignable_v<const first_type&, const _U1&> &&
393bdd1243dSDimitry Andric                is_assignable_v<const second_type&, const _U2&>) {
394bdd1243dSDimitry Andric         first = __p.first;
395bdd1243dSDimitry Andric         second = __p.second;
396bdd1243dSDimitry Andric         return *this;
397bdd1243dSDimitry Andric     }
398bdd1243dSDimitry Andric 
399bdd1243dSDimitry Andric     template<class _U1, class _U2>
400bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr
401bdd1243dSDimitry Andric     const pair& operator=(pair<_U1, _U2>&& __p) const
402bdd1243dSDimitry Andric       requires(is_assignable_v<const first_type&, _U1> &&
403bdd1243dSDimitry Andric                is_assignable_v<const second_type&, _U2>) {
404bdd1243dSDimitry Andric         first = std::forward<_U1>(__p.first);
405bdd1243dSDimitry Andric         second = std::forward<_U2>(__p.second);
406bdd1243dSDimitry Andric         return *this;
407bdd1243dSDimitry Andric     }
408bdd1243dSDimitry Andric 
409*06c3fb27SDimitry Andric     template <__pair_like _PairLike>
410*06c3fb27SDimitry Andric       requires(__different_from<_PairLike, pair> &&
411*06c3fb27SDimitry Andric                !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
412*06c3fb27SDimitry Andric                is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
413*06c3fb27SDimitry Andric                is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>)
414*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) {
415*06c3fb27SDimitry Andric         first  = std::get<0>(std::forward<_PairLike>(__p));
416*06c3fb27SDimitry Andric         second = std::get<1>(std::forward<_PairLike>(__p));
417fe6060f1SDimitry Andric         return *this;
418fe6060f1SDimitry Andric     }
419fe6060f1SDimitry Andric 
420*06c3fb27SDimitry Andric     template <__pair_like _PairLike>
421*06c3fb27SDimitry Andric       requires(__different_from<_PairLike, pair> &&
422*06c3fb27SDimitry Andric                !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
423*06c3fb27SDimitry Andric                is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
424*06c3fb27SDimitry Andric                is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>)
425*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const {
426*06c3fb27SDimitry Andric         first  = std::get<0>(std::forward<_PairLike>(__p));
427*06c3fb27SDimitry Andric         second = std::get<1>(std::forward<_PairLike>(__p));
428*06c3fb27SDimitry Andric         return *this;
429*06c3fb27SDimitry Andric     }
430*06c3fb27SDimitry Andric #  endif // _LIBCPP_STD_VER >= 23
431*06c3fb27SDimitry Andric 
432*06c3fb27SDimitry Andric     // Prior to C++23, we provide an approximation of constructors and assignment operators from
433*06c3fb27SDimitry Andric     // pair-like types. This was historically provided as an extension.
434*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER < 23
435*06c3fb27SDimitry Andric     // from std::tuple
436*06c3fb27SDimitry Andric     template<class _U1, class _U2, __enable_if_t<
437*06c3fb27SDimitry Andric         is_convertible<_U1 const&, _T1>::value &&
438*06c3fb27SDimitry Andric         is_convertible<_U2 const&, _T2>::value
439*06c3fb27SDimitry Andric     >* = nullptr>
440*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
441*06c3fb27SDimitry Andric     pair(tuple<_U1, _U2> const& __p)
442*06c3fb27SDimitry Andric         : first(std::get<0>(__p)),
443*06c3fb27SDimitry Andric           second(std::get<1>(__p)) {}
444*06c3fb27SDimitry Andric 
445*06c3fb27SDimitry Andric     template<class _U1, class _U2, __enable_if_t<
446*06c3fb27SDimitry Andric         is_constructible<_T1, _U1 const&>::value &&
447*06c3fb27SDimitry Andric         is_constructible<_T2, _U2 const&>::value &&
448*06c3fb27SDimitry Andric         !(is_convertible<_U1 const&, _T1>::value &&
449*06c3fb27SDimitry Andric           is_convertible<_U2 const&, _T2>::value)
450*06c3fb27SDimitry Andric     >* = nullptr>
451*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
452*06c3fb27SDimitry Andric     explicit
453*06c3fb27SDimitry Andric     pair(tuple<_U1, _U2> const& __p)
454*06c3fb27SDimitry Andric         : first(std::get<0>(__p)),
455*06c3fb27SDimitry Andric           second(std::get<1>(__p)) {}
456*06c3fb27SDimitry Andric 
457*06c3fb27SDimitry Andric     template<class _U1, class _U2, __enable_if_t<
458*06c3fb27SDimitry Andric         is_convertible<_U1, _T1>::value &&
459*06c3fb27SDimitry Andric         is_convertible<_U2, _T2>::value
460*06c3fb27SDimitry Andric     >* = nullptr>
461*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
462*06c3fb27SDimitry Andric     pair(tuple<_U1, _U2>&& __p)
463*06c3fb27SDimitry Andric         : first(std::get<0>(std::move(__p))),
464*06c3fb27SDimitry Andric           second(std::get<1>(std::move(__p))) {}
465*06c3fb27SDimitry Andric 
466*06c3fb27SDimitry Andric     template<class _U1, class _U2, __enable_if_t<
467*06c3fb27SDimitry Andric         is_constructible<_T1, _U1>::value &&
468*06c3fb27SDimitry Andric         is_constructible<_T2, _U2>::value &&
469*06c3fb27SDimitry Andric         !(is_convertible<_U1, _T1>::value &&
470*06c3fb27SDimitry Andric           is_convertible<_U2, _T2>::value)
471*06c3fb27SDimitry Andric     >* = nullptr>
472*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
473*06c3fb27SDimitry Andric     explicit
474*06c3fb27SDimitry Andric     pair(tuple<_U1, _U2>&& __p)
475*06c3fb27SDimitry Andric         : first(std::get<0>(std::move(__p))),
476*06c3fb27SDimitry Andric           second(std::get<1>(std::move(__p))) {}
477*06c3fb27SDimitry Andric 
478*06c3fb27SDimitry Andric 
479*06c3fb27SDimitry Andric     template<class _U1, class _U2, __enable_if_t<
480*06c3fb27SDimitry Andric         is_assignable<_T1&, _U1 const&>::value &&
481*06c3fb27SDimitry Andric         is_assignable<_T2&, _U2 const&>::value
482*06c3fb27SDimitry Andric     >* = nullptr>
483*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
484*06c3fb27SDimitry Andric     pair& operator=(tuple<_U1, _U2> const& __p) {
485*06c3fb27SDimitry Andric         first = std::get<0>(__p);
486*06c3fb27SDimitry Andric         second = std::get<1>(__p);
487*06c3fb27SDimitry Andric         return *this;
488*06c3fb27SDimitry Andric     }
489*06c3fb27SDimitry Andric 
490*06c3fb27SDimitry Andric     template<class _U1, class _U2, __enable_if_t<
491*06c3fb27SDimitry Andric         is_assignable<_T1&, _U1&&>::value &&
492*06c3fb27SDimitry Andric         is_assignable<_T2&, _U2&&>::value
493*06c3fb27SDimitry Andric     >* = nullptr>
494*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
495*06c3fb27SDimitry Andric     pair& operator=(tuple<_U1, _U2>&& __p) {
496*06c3fb27SDimitry Andric         first = std::get<0>(std::move(__p));
497*06c3fb27SDimitry Andric         second = std::get<1>(std::move(__p));
498*06c3fb27SDimitry Andric         return *this;
499*06c3fb27SDimitry Andric     }
500*06c3fb27SDimitry Andric 
501*06c3fb27SDimitry Andric     // from std::array
502*06c3fb27SDimitry Andric     template<class _Up, __enable_if_t<
503*06c3fb27SDimitry Andric         is_convertible<_Up const&, _T1>::value &&
504*06c3fb27SDimitry Andric         is_convertible<_Up const&, _T2>::value
505*06c3fb27SDimitry Andric     >* = nullptr>
506*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
507*06c3fb27SDimitry Andric     pair(array<_Up, 2> const& __p)
508*06c3fb27SDimitry Andric         : first(__p[0]),
509*06c3fb27SDimitry Andric           second(__p[1]) {}
510*06c3fb27SDimitry Andric 
511*06c3fb27SDimitry Andric     template<class _Up, __enable_if_t<
512*06c3fb27SDimitry Andric         is_constructible<_T1, _Up const&>::value &&
513*06c3fb27SDimitry Andric         is_constructible<_T2, _Up const&>::value &&
514*06c3fb27SDimitry Andric         !(is_convertible<_Up const&, _T1>::value &&
515*06c3fb27SDimitry Andric           is_convertible<_Up const&, _T2>::value)
516*06c3fb27SDimitry Andric     >* = nullptr>
517*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
518*06c3fb27SDimitry Andric     explicit
519*06c3fb27SDimitry Andric     pair(array<_Up, 2> const& __p)
520*06c3fb27SDimitry Andric         : first(__p[0]),
521*06c3fb27SDimitry Andric           second(__p[1]) {}
522*06c3fb27SDimitry Andric 
523*06c3fb27SDimitry Andric     template<class _Up, __enable_if_t<
524*06c3fb27SDimitry Andric         is_convertible<_Up, _T1>::value &&
525*06c3fb27SDimitry Andric         is_convertible<_Up, _T2>::value
526*06c3fb27SDimitry Andric     >* = nullptr>
527*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
528*06c3fb27SDimitry Andric     pair(array<_Up, 2>&& __p)
529*06c3fb27SDimitry Andric         : first(std::move(__p)[0]),
530*06c3fb27SDimitry Andric           second(std::move(__p)[1]) {}
531*06c3fb27SDimitry Andric 
532*06c3fb27SDimitry Andric     template<class _Up, __enable_if_t<
533*06c3fb27SDimitry Andric         is_constructible<_T1, _Up>::value &&
534*06c3fb27SDimitry Andric         is_constructible<_T2, _Up>::value &&
535*06c3fb27SDimitry Andric         !(is_convertible<_Up, _T1>::value &&
536*06c3fb27SDimitry Andric           is_convertible<_Up, _T2>::value)
537*06c3fb27SDimitry Andric     >* = nullptr>
538*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
539*06c3fb27SDimitry Andric     explicit
540*06c3fb27SDimitry Andric     pair(array<_Up, 2>&& __p)
541*06c3fb27SDimitry Andric         : first(std::move(__p)[0]),
542*06c3fb27SDimitry Andric           second(std::move(__p)[1]) {}
543*06c3fb27SDimitry Andric 
544*06c3fb27SDimitry Andric 
545*06c3fb27SDimitry Andric     template<class _Up, __enable_if_t<
546*06c3fb27SDimitry Andric         is_assignable<_T1&, _Up const&>::value &&
547*06c3fb27SDimitry Andric         is_assignable<_T2&, _Up const&>::value
548*06c3fb27SDimitry Andric     >* = nullptr>
549*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
550*06c3fb27SDimitry Andric     pair& operator=(array<_Up, 2> const& __p) {
551*06c3fb27SDimitry Andric         first = std::get<0>(__p);
552*06c3fb27SDimitry Andric         second = std::get<1>(__p);
553*06c3fb27SDimitry Andric         return *this;
554*06c3fb27SDimitry Andric     }
555*06c3fb27SDimitry Andric 
556*06c3fb27SDimitry Andric     template<class _Up, __enable_if_t<
557*06c3fb27SDimitry Andric         is_assignable<_T1&, _Up>::value &&
558*06c3fb27SDimitry Andric         is_assignable<_T2&, _Up>::value
559*06c3fb27SDimitry Andric     >* = nullptr>
560*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
561*06c3fb27SDimitry Andric     pair& operator=(array<_Up, 2>&& __p) {
562*06c3fb27SDimitry Andric         first = std::get<0>(std::move(__p));
563*06c3fb27SDimitry Andric         second = std::get<1>(std::move(__p));
564*06c3fb27SDimitry Andric         return *this;
565*06c3fb27SDimitry Andric     }
566*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER < 23
567*06c3fb27SDimitry Andric #endif // _LIBCPP_CXX03_LANG
568*06c3fb27SDimitry Andric 
569*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
570fe6060f1SDimitry Andric     void
571fe6060f1SDimitry Andric     swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
572fe6060f1SDimitry Andric                                __is_nothrow_swappable<second_type>::value)
573fe6060f1SDimitry Andric     {
574*06c3fb27SDimitry Andric         using std::swap;
575fe6060f1SDimitry Andric         swap(first,  __p.first);
576fe6060f1SDimitry Andric         swap(second, __p.second);
577fe6060f1SDimitry Andric     }
578bdd1243dSDimitry Andric 
579*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23
580bdd1243dSDimitry Andric     _LIBCPP_HIDE_FROM_ABI constexpr
581bdd1243dSDimitry Andric     void swap(const pair& __p) const
582bdd1243dSDimitry Andric         noexcept(__is_nothrow_swappable<const first_type>::value &&
583bdd1243dSDimitry Andric                  __is_nothrow_swappable<const second_type>::value)
584bdd1243dSDimitry Andric     {
585bdd1243dSDimitry Andric         using std::swap;
586bdd1243dSDimitry Andric         swap(first,  __p.first);
587bdd1243dSDimitry Andric         swap(second, __p.second);
588bdd1243dSDimitry Andric     }
589bdd1243dSDimitry Andric #endif
590fe6060f1SDimitry Andric private:
591fe6060f1SDimitry Andric 
592fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG
593fe6060f1SDimitry Andric     template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
594*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
595fe6060f1SDimitry Andric     pair(piecewise_construct_t,
596fe6060f1SDimitry Andric          tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
597fe6060f1SDimitry Andric          __tuple_indices<_I1...>, __tuple_indices<_I2...>);
598fe6060f1SDimitry Andric #endif
599fe6060f1SDimitry Andric };
600fe6060f1SDimitry Andric 
601*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 17
602fe6060f1SDimitry Andric template<class _T1, class _T2>
603fe6060f1SDimitry Andric pair(_T1, _T2) -> pair<_T1, _T2>;
604349cc55cSDimitry Andric #endif
605349cc55cSDimitry Andric 
606349cc55cSDimitry Andric // [pairs.spec], specialized algorithms
607fe6060f1SDimitry Andric 
608*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2>
609*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
610fe6060f1SDimitry Andric bool
611*06c3fb27SDimitry Andric operator==(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
612fe6060f1SDimitry Andric {
613fe6060f1SDimitry Andric     return __x.first == __y.first && __x.second == __y.second;
614fe6060f1SDimitry Andric }
615fe6060f1SDimitry Andric 
616*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
617349cc55cSDimitry Andric 
618*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2>
619349cc55cSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr
620349cc55cSDimitry Andric common_comparison_category_t<
621*06c3fb27SDimitry Andric         __synth_three_way_result<_T1, _U1>,
622*06c3fb27SDimitry Andric         __synth_three_way_result<_T2, _U2> >
623*06c3fb27SDimitry Andric operator<=>(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
624349cc55cSDimitry Andric {
625*06c3fb27SDimitry Andric     if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) {
626349cc55cSDimitry Andric       return __c;
627349cc55cSDimitry Andric     }
628*06c3fb27SDimitry Andric     return std::__synth_three_way(__x.second, __y.second);
629349cc55cSDimitry Andric }
630349cc55cSDimitry Andric 
631*06c3fb27SDimitry Andric #else // _LIBCPP_STD_VER >= 20
632349cc55cSDimitry Andric 
633*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2>
634*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
635fe6060f1SDimitry Andric bool
636*06c3fb27SDimitry Andric operator!=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
637fe6060f1SDimitry Andric {
638fe6060f1SDimitry Andric     return !(__x == __y);
639fe6060f1SDimitry Andric }
640fe6060f1SDimitry Andric 
641*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2>
642*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
643fe6060f1SDimitry Andric bool
644*06c3fb27SDimitry Andric operator< (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
645fe6060f1SDimitry Andric {
646fe6060f1SDimitry Andric     return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
647fe6060f1SDimitry Andric }
648fe6060f1SDimitry Andric 
649*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2>
650*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
651fe6060f1SDimitry Andric bool
652*06c3fb27SDimitry Andric operator> (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
653fe6060f1SDimitry Andric {
654fe6060f1SDimitry Andric     return __y < __x;
655fe6060f1SDimitry Andric }
656fe6060f1SDimitry Andric 
657*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2>
658*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
659fe6060f1SDimitry Andric bool
660*06c3fb27SDimitry Andric operator>=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
661fe6060f1SDimitry Andric {
662fe6060f1SDimitry Andric     return !(__x < __y);
663fe6060f1SDimitry Andric }
664fe6060f1SDimitry Andric 
665*06c3fb27SDimitry Andric template <class _T1, class _T2, class _U1, class _U2>
666*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
667fe6060f1SDimitry Andric bool
668*06c3fb27SDimitry Andric operator<=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
669fe6060f1SDimitry Andric {
670fe6060f1SDimitry Andric     return !(__y < __x);
671fe6060f1SDimitry Andric }
672fe6060f1SDimitry Andric 
673*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 20
67481ad6265SDimitry Andric 
675*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23
67681ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2, template<class> class _TQual, template<class> class _UQual>
67781ad6265SDimitry Andric     requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
67881ad6265SDimitry Andric                                       common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
67981ad6265SDimitry Andric struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> {
68081ad6265SDimitry Andric     using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
68181ad6265SDimitry Andric                       common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
68281ad6265SDimitry Andric };
68381ad6265SDimitry Andric 
68481ad6265SDimitry Andric template <class _T1, class _T2, class _U1, class _U2>
68581ad6265SDimitry Andric     requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
68681ad6265SDimitry Andric struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> {
68781ad6265SDimitry Andric     using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>;
68881ad6265SDimitry Andric };
689*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 23
690349cc55cSDimitry Andric 
691fe6060f1SDimitry Andric template <class _T1, class _T2>
692*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
693fe6060f1SDimitry Andric typename enable_if
694fe6060f1SDimitry Andric <
695fe6060f1SDimitry Andric     __is_swappable<_T1>::value &&
696fe6060f1SDimitry Andric     __is_swappable<_T2>::value,
697fe6060f1SDimitry Andric     void
698fe6060f1SDimitry Andric >::type
699fe6060f1SDimitry Andric swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
700fe6060f1SDimitry Andric                      _NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&
701fe6060f1SDimitry Andric                                  __is_nothrow_swappable<_T2>::value))
702fe6060f1SDimitry Andric {
703fe6060f1SDimitry Andric     __x.swap(__y);
704fe6060f1SDimitry Andric }
705fe6060f1SDimitry Andric 
706*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 23
707bdd1243dSDimitry Andric template <class _T1, class _T2>
708bdd1243dSDimitry Andric   requires (__is_swappable<const _T1>::value &&
709bdd1243dSDimitry Andric             __is_swappable<const _T2>::value)
710bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr
711bdd1243dSDimitry Andric void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
712bdd1243dSDimitry Andric     noexcept(noexcept(__x.swap(__y)))
713bdd1243dSDimitry Andric {
714bdd1243dSDimitry Andric     __x.swap(__y);
715bdd1243dSDimitry Andric }
716bdd1243dSDimitry Andric #endif
717fe6060f1SDimitry Andric 
718fe6060f1SDimitry Andric template <class _T1, class _T2>
719*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
720fe6060f1SDimitry Andric pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
721fe6060f1SDimitry Andric make_pair(_T1&& __t1, _T2&& __t2)
722fe6060f1SDimitry Andric {
723fe6060f1SDimitry Andric     return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
724*06c3fb27SDimitry Andric                (std::forward<_T1>(__t1), std::forward<_T2>(__t2));
725fe6060f1SDimitry Andric }
726fe6060f1SDimitry Andric 
727fe6060f1SDimitry Andric template <class _T1, class _T2>
728fe6060f1SDimitry Andric   struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
729fe6060f1SDimitry Andric     : public integral_constant<size_t, 2> {};
730fe6060f1SDimitry Andric 
731fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2>
732fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
733fe6060f1SDimitry Andric {
734fe6060f1SDimitry Andric     static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
735fe6060f1SDimitry Andric };
736fe6060f1SDimitry Andric 
737fe6060f1SDimitry Andric template <class _T1, class _T2>
738fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
739fe6060f1SDimitry Andric {
740*06c3fb27SDimitry Andric     using type _LIBCPP_NODEBUG = _T1;
741fe6060f1SDimitry Andric };
742fe6060f1SDimitry Andric 
743fe6060f1SDimitry Andric template <class _T1, class _T2>
744fe6060f1SDimitry Andric struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
745fe6060f1SDimitry Andric {
746*06c3fb27SDimitry Andric     using type _LIBCPP_NODEBUG = _T2;
747fe6060f1SDimitry Andric };
748fe6060f1SDimitry Andric 
749fe6060f1SDimitry Andric template <size_t _Ip> struct __get_pair;
750fe6060f1SDimitry Andric 
751fe6060f1SDimitry Andric template <>
752fe6060f1SDimitry Andric struct __get_pair<0>
753fe6060f1SDimitry Andric {
754fe6060f1SDimitry Andric     template <class _T1, class _T2>
755fe6060f1SDimitry Andric     static
756*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
757fe6060f1SDimitry Andric     _T1&
758fe6060f1SDimitry Andric     get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
759fe6060f1SDimitry Andric 
760fe6060f1SDimitry Andric     template <class _T1, class _T2>
761fe6060f1SDimitry Andric     static
762*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
763fe6060f1SDimitry Andric     const _T1&
764fe6060f1SDimitry Andric     get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
765fe6060f1SDimitry Andric 
766fe6060f1SDimitry Andric     template <class _T1, class _T2>
767fe6060f1SDimitry Andric     static
768*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
769fe6060f1SDimitry Andric     _T1&&
770*06c3fb27SDimitry Andric     get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T1>(__p.first);}
771fe6060f1SDimitry Andric 
772fe6060f1SDimitry Andric     template <class _T1, class _T2>
773fe6060f1SDimitry Andric     static
774*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
775fe6060f1SDimitry Andric     const _T1&&
776*06c3fb27SDimitry Andric     get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T1>(__p.first);}
777fe6060f1SDimitry Andric };
778fe6060f1SDimitry Andric 
779fe6060f1SDimitry Andric template <>
780fe6060f1SDimitry Andric struct __get_pair<1>
781fe6060f1SDimitry Andric {
782fe6060f1SDimitry Andric     template <class _T1, class _T2>
783fe6060f1SDimitry Andric     static
784*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
785fe6060f1SDimitry Andric     _T2&
786fe6060f1SDimitry Andric     get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
787fe6060f1SDimitry Andric 
788fe6060f1SDimitry Andric     template <class _T1, class _T2>
789fe6060f1SDimitry Andric     static
790*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
791fe6060f1SDimitry Andric     const _T2&
792fe6060f1SDimitry Andric     get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
793fe6060f1SDimitry Andric 
794fe6060f1SDimitry Andric     template <class _T1, class _T2>
795fe6060f1SDimitry Andric     static
796*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
797fe6060f1SDimitry Andric     _T2&&
798*06c3fb27SDimitry Andric     get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T2>(__p.second);}
799fe6060f1SDimitry Andric 
800fe6060f1SDimitry Andric     template <class _T1, class _T2>
801fe6060f1SDimitry Andric     static
802*06c3fb27SDimitry Andric     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
803fe6060f1SDimitry Andric     const _T2&&
804*06c3fb27SDimitry Andric     get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T2>(__p.second);}
805fe6060f1SDimitry Andric };
806fe6060f1SDimitry Andric 
807fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2>
808*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
809fe6060f1SDimitry Andric typename tuple_element<_Ip, pair<_T1, _T2> >::type&
810fe6060f1SDimitry Andric get(pair<_T1, _T2>& __p) _NOEXCEPT
811fe6060f1SDimitry Andric {
812fe6060f1SDimitry Andric     return __get_pair<_Ip>::get(__p);
813fe6060f1SDimitry Andric }
814fe6060f1SDimitry Andric 
815fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2>
816*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
817fe6060f1SDimitry Andric const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
818fe6060f1SDimitry Andric get(const pair<_T1, _T2>& __p) _NOEXCEPT
819fe6060f1SDimitry Andric {
820fe6060f1SDimitry Andric     return __get_pair<_Ip>::get(__p);
821fe6060f1SDimitry Andric }
822fe6060f1SDimitry Andric 
823fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2>
824*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
825fe6060f1SDimitry Andric typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
826fe6060f1SDimitry Andric get(pair<_T1, _T2>&& __p) _NOEXCEPT
827fe6060f1SDimitry Andric {
828*06c3fb27SDimitry Andric     return __get_pair<_Ip>::get(std::move(__p));
829fe6060f1SDimitry Andric }
830fe6060f1SDimitry Andric 
831fe6060f1SDimitry Andric template <size_t _Ip, class _T1, class _T2>
832*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
833fe6060f1SDimitry Andric const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
834fe6060f1SDimitry Andric get(const pair<_T1, _T2>&& __p) _NOEXCEPT
835fe6060f1SDimitry Andric {
836*06c3fb27SDimitry Andric     return __get_pair<_Ip>::get(std::move(__p));
837fe6060f1SDimitry Andric }
838fe6060f1SDimitry Andric 
839*06c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 14
840fe6060f1SDimitry Andric template <class _T1, class _T2>
841*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
842fe6060f1SDimitry Andric constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
843fe6060f1SDimitry Andric {
844fe6060f1SDimitry Andric     return __get_pair<0>::get(__p);
845fe6060f1SDimitry Andric }
846fe6060f1SDimitry Andric 
847fe6060f1SDimitry Andric template <class _T1, class _T2>
848*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
849fe6060f1SDimitry Andric constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
850fe6060f1SDimitry Andric {
851fe6060f1SDimitry Andric     return __get_pair<0>::get(__p);
852fe6060f1SDimitry Andric }
853fe6060f1SDimitry Andric 
854fe6060f1SDimitry Andric template <class _T1, class _T2>
855*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
856fe6060f1SDimitry Andric constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
857fe6060f1SDimitry Andric {
858*06c3fb27SDimitry Andric     return __get_pair<0>::get(std::move(__p));
859fe6060f1SDimitry Andric }
860fe6060f1SDimitry Andric 
861fe6060f1SDimitry Andric template <class _T1, class _T2>
862*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
863fe6060f1SDimitry Andric constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT
864fe6060f1SDimitry Andric {
865*06c3fb27SDimitry Andric     return __get_pair<0>::get(std::move(__p));
866fe6060f1SDimitry Andric }
867fe6060f1SDimitry Andric 
868fe6060f1SDimitry Andric template <class _T1, class _T2>
869*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
870fe6060f1SDimitry Andric constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
871fe6060f1SDimitry Andric {
872fe6060f1SDimitry Andric     return __get_pair<1>::get(__p);
873fe6060f1SDimitry Andric }
874fe6060f1SDimitry Andric 
875fe6060f1SDimitry Andric template <class _T1, class _T2>
876*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
877fe6060f1SDimitry Andric constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
878fe6060f1SDimitry Andric {
879fe6060f1SDimitry Andric     return __get_pair<1>::get(__p);
880fe6060f1SDimitry Andric }
881fe6060f1SDimitry Andric 
882fe6060f1SDimitry Andric template <class _T1, class _T2>
883*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
884fe6060f1SDimitry Andric constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
885fe6060f1SDimitry Andric {
886*06c3fb27SDimitry Andric     return __get_pair<1>::get(std::move(__p));
887fe6060f1SDimitry Andric }
888fe6060f1SDimitry Andric 
889fe6060f1SDimitry Andric template <class _T1, class _T2>
890*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI
891fe6060f1SDimitry Andric constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT
892fe6060f1SDimitry Andric {
893*06c3fb27SDimitry Andric     return __get_pair<1>::get(std::move(__p));
894fe6060f1SDimitry Andric }
895fe6060f1SDimitry Andric 
896*06c3fb27SDimitry Andric #endif // _LIBCPP_STD_VER >= 14
897fe6060f1SDimitry Andric 
898fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD
899fe6060f1SDimitry Andric 
900*06c3fb27SDimitry Andric _LIBCPP_POP_MACROS
901*06c3fb27SDimitry Andric 
902fe6060f1SDimitry Andric #endif // _LIBCPP___UTILITY_PAIR_H
903