xref: /freebsd/contrib/llvm-project/libcxx/include/__utility/pair.h (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef _LIBCPP___UTILITY_PAIR_H
10 #define _LIBCPP___UTILITY_PAIR_H
11 
12 #include <__compare/common_comparison_category.h>
13 #include <__compare/synth_three_way.h>
14 #include <__concepts/different_from.h>
15 #include <__config>
16 #include <__fwd/array.h>
17 #include <__fwd/get.h>
18 #include <__fwd/pair.h>
19 #include <__fwd/subrange.h>
20 #include <__fwd/tuple.h>
21 #include <__tuple/pair_like.h>
22 #include <__tuple/sfinae_helpers.h>
23 #include <__tuple/tuple_element.h>
24 #include <__tuple/tuple_indices.h>
25 #include <__tuple/tuple_size.h>
26 #include <__type_traits/common_reference.h>
27 #include <__type_traits/common_type.h>
28 #include <__type_traits/conditional.h>
29 #include <__type_traits/decay.h>
30 #include <__type_traits/integral_constant.h>
31 #include <__type_traits/is_assignable.h>
32 #include <__type_traits/is_constructible.h>
33 #include <__type_traits/is_convertible.h>
34 #include <__type_traits/is_copy_assignable.h>
35 #include <__type_traits/is_default_constructible.h>
36 #include <__type_traits/is_implicitly_default_constructible.h>
37 #include <__type_traits/is_move_assignable.h>
38 #include <__type_traits/is_nothrow_assignable.h>
39 #include <__type_traits/is_nothrow_constructible.h>
40 #include <__type_traits/is_nothrow_copy_assignable.h>
41 #include <__type_traits/is_nothrow_copy_constructible.h>
42 #include <__type_traits/is_nothrow_default_constructible.h>
43 #include <__type_traits/is_nothrow_move_assignable.h>
44 #include <__type_traits/is_same.h>
45 #include <__type_traits/is_swappable.h>
46 #include <__type_traits/nat.h>
47 #include <__type_traits/remove_cvref.h>
48 #include <__type_traits/unwrap_ref.h>
49 #include <__utility/declval.h>
50 #include <__utility/forward.h>
51 #include <__utility/move.h>
52 #include <__utility/piecewise_construct.h>
53 #include <cstddef>
54 
55 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
56 #  pragma GCC system_header
57 #endif
58 
59 _LIBCPP_PUSH_MACROS
60 #include <__undef_macros>
61 
62 _LIBCPP_BEGIN_NAMESPACE_STD
63 
64 template <class, class>
65 struct __non_trivially_copyable_base {
66   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __non_trivially_copyable_base() _NOEXCEPT {}
67   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
68   __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
69 };
70 
71 #if _LIBCPP_STD_VER >= 23
72 template <class _Tp>
73 struct __is_specialization_of_subrange : false_type {};
74 
75 template <class _Iter, class _Sent, ranges::subrange_kind _Kind>
76 struct __is_specialization_of_subrange<ranges::subrange<_Iter, _Sent, _Kind>> : true_type {};
77 #endif
78 
79 template <class _T1, class _T2>
80 struct _LIBCPP_TEMPLATE_VIS pair
81 #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
82     : private __non_trivially_copyable_base<_T1, _T2>
83 #endif
84 {
85   using first_type  = _T1;
86   using second_type = _T2;
87 
88   _T1 first;
89   _T2 second;
90 
91   _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
92   _LIBCPP_HIDE_FROM_ABI pair(pair&&)      = default;
93 
94 #ifdef _LIBCPP_CXX03_LANG
95   _LIBCPP_HIDE_FROM_ABI pair() : first(), second() {}
96 
97   _LIBCPP_HIDE_FROM_ABI pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
98 
99   template <class _U1, class _U2>
100   _LIBCPP_HIDE_FROM_ABI pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
101 
102   _LIBCPP_HIDE_FROM_ABI pair& operator=(pair const& __p) {
103     first  = __p.first;
104     second = __p.second;
105     return *this;
106   }
107 
108   // Extension: This is provided in C++03 because it allows properly handling the
109   //            assignment to a pair containing references, which would be a hard
110   //            error otherwise.
111   template <class _U1,
112             class _U2,
113             class = __enable_if_t< is_assignable<first_type&, _U1 const&>::value &&
114                                    is_assignable<second_type&, _U2 const&>::value > >
115   _LIBCPP_HIDE_FROM_ABI pair& operator=(pair<_U1, _U2> const& __p) {
116     first  = __p.first;
117     second = __p.second;
118     return *this;
119   }
120 #else
121   struct _CheckArgs {
122     template <int&...>
123     static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() {
124       return is_default_constructible<_T1>::value && is_default_constructible<_T2>::value &&
125              !__enable_implicit_default<>();
126     }
127 
128     template <int&...>
129     static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() {
130       return __is_implicitly_default_constructible<_T1>::value && __is_implicitly_default_constructible<_T2>::value;
131     }
132 
133     template <class _U1, class _U2>
134     static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() {
135       return is_constructible<first_type, _U1>::value && is_constructible<second_type, _U2>::value;
136     }
137 
138     template <class _U1, class _U2>
139     static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() {
140       return is_convertible<_U1, first_type>::value && is_convertible<_U2, second_type>::value;
141     }
142 
143     template <class _U1, class _U2>
144     static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() {
145       return __is_pair_constructible<_U1, _U2>() && !__is_implicit<_U1, _U2>();
146     }
147 
148     template <class _U1, class _U2>
149     static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() {
150       return __is_pair_constructible<_U1, _U2>() && __is_implicit<_U1, _U2>();
151     }
152   };
153 
154   template <bool _MaybeEnable>
155   using _CheckArgsDep _LIBCPP_NODEBUG =
156       typename conditional< _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
157 
158   template <bool _Dummy = true, __enable_if_t<_CheckArgsDep<_Dummy>::__enable_explicit_default(), int> = 0>
159   explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair() _NOEXCEPT_(
160       is_nothrow_default_constructible<first_type>::value&& is_nothrow_default_constructible<second_type>::value)
161       : first(), second() {}
162 
163   template <bool _Dummy = true, __enable_if_t<_CheckArgsDep<_Dummy>::__enable_implicit_default(), int> = 0>
164   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair() _NOEXCEPT_(
165       is_nothrow_default_constructible<first_type>::value&& is_nothrow_default_constructible<second_type>::value)
166       : first(), second() {}
167 
168   template <bool _Dummy                                                                                     = true,
169             __enable_if_t<_CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>(), int> = 0>
170   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(_T1 const& __t1, _T2 const& __t2)
171       _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value&& is_nothrow_copy_constructible<second_type>::value)
172       : first(__t1), second(__t2) {}
173 
174   template <bool _Dummy                                                                                     = true,
175             __enable_if_t<_CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>(), int> = 0>
176   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(_T1 const& __t1, _T2 const& __t2)
177       _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value&& is_nothrow_copy_constructible<second_type>::value)
178       : first(__t1), second(__t2) {}
179 
180   template <
181 #  if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
182       class _U1 = _T1,
183       class _U2 = _T2,
184 #  else
185       class _U1,
186       class _U2,
187 #  endif
188       __enable_if_t<_CheckArgs::template __enable_explicit<_U1, _U2>(), int> = 0 >
189   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(_U1&& __u1, _U2&& __u2)
190       _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
191                   is_nothrow_constructible<second_type, _U2>::value))
192       : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {
193   }
194 
195   template <
196 #  if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
197       class _U1 = _T1,
198       class _U2 = _T2,
199 #  else
200       class _U1,
201       class _U2,
202 #  endif
203       __enable_if_t<_CheckArgs::template __enable_implicit<_U1, _U2>(), int> = 0 >
204   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(_U1&& __u1, _U2&& __u2)
205       _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
206                   is_nothrow_constructible<second_type, _U2>::value))
207       : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {
208   }
209 
210 #  if _LIBCPP_STD_VER >= 23
211   template <class _U1,
212             class _U2,
213             __enable_if_t< _CheckArgs::template __is_pair_constructible<_U1&, _U2&>() >* = nullptr>
214   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>())
215       pair(pair<_U1, _U2>& __p) noexcept((is_nothrow_constructible<first_type, _U1&>::value &&
216                                           is_nothrow_constructible<second_type, _U2&>::value))
217       : first(__p.first), second(__p.second) {}
218 #  endif
219 
220   template <class _U1,
221             class _U2,
222             __enable_if_t<_CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>(), int> = 0>
223   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(pair<_U1, _U2> const& __p)
224       _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
225                   is_nothrow_constructible<second_type, _U2 const&>::value))
226       : first(__p.first), second(__p.second) {}
227 
228   template <class _U1,
229             class _U2,
230             __enable_if_t<_CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>(), int> = 0>
231   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(pair<_U1, _U2> const& __p)
232       _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
233                   is_nothrow_constructible<second_type, _U2 const&>::value))
234       : first(__p.first), second(__p.second) {}
235 
236   template <class _U1, class _U2, __enable_if_t<_CheckArgs::template __enable_explicit<_U1, _U2>(), int> = 0>
237   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(pair<_U1, _U2>&& __p)
238       _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
239                   is_nothrow_constructible<second_type, _U2&&>::value))
240       : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
241 
242   template <class _U1, class _U2, __enable_if_t<_CheckArgs::template __enable_implicit<_U1, _U2>(), int> = 0>
243   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(pair<_U1, _U2>&& __p)
244       _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
245                   is_nothrow_constructible<second_type, _U2&&>::value))
246       : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
247 
248 #  if _LIBCPP_STD_VER >= 23
249   template <class _U1,
250             class _U2,
251             __enable_if_t< _CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>() >* = nullptr>
252   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!_CheckArgs::template __is_implicit<const _U1&&, const _U2&&>())
253       pair(const pair<_U1, _U2>&& __p) noexcept(is_nothrow_constructible<first_type, const _U1&&>::value &&
254                                                 is_nothrow_constructible<second_type, const _U2&&>::value)
255       : first(std::move(__p.first)), second(std::move(__p.second)) {}
256 #  endif
257 
258 #  if _LIBCPP_STD_VER >= 23
259   // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed.
260   template <class _PairLike>
261   _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() {
262     if constexpr (__pair_like<_PairLike>) {
263       return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> ||
264              !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>;
265     }
266     return false;
267   }
268 
269   template <__pair_like _PairLike>
270     requires(!__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
271              is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike &&>()))> &&
272              is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike &&>()))>)
273   _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>()) pair(_PairLike&& __p)
274       : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {}
275 #  endif
276 
277   template <class... _Args1, class... _Args2>
278   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
279   pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
280       _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
281                   is_nothrow_constructible<second_type, _Args2...>::value))
282       : pair(__pc,
283              __first_args,
284              __second_args,
285              typename __make_tuple_indices<sizeof...(_Args1)>::type(),
286              typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
287 
288   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair&
289   operator=(__conditional_t< is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value,
290                              pair,
291                              __nat> const& __p)
292       _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value&& is_nothrow_copy_assignable<second_type>::value) {
293     first  = __p.first;
294     second = __p.second;
295     return *this;
296   }
297 
298   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(
299       __conditional_t< is_move_assignable<first_type>::value && is_move_assignable<second_type>::value, pair, __nat>&&
300           __p)
301       _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value&& is_nothrow_move_assignable<second_type>::value) {
302     first  = std::forward<first_type>(__p.first);
303     second = std::forward<second_type>(__p.second);
304     return *this;
305   }
306 
307   template <class _U1,
308             class _U2,
309             __enable_if_t< is_assignable<first_type&, _U1 const&>::value &&
310                            is_assignable<second_type&, _U2 const&>::value >* = nullptr>
311   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2> const& __p) {
312     first  = __p.first;
313     second = __p.second;
314     return *this;
315   }
316 
317   template <
318       class _U1,
319       class _U2,
320       __enable_if_t< is_assignable<first_type&, _U1>::value && is_assignable<second_type&, _U2>::value >* = nullptr>
321   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(pair<_U1, _U2>&& __p) {
322     first  = std::forward<_U1>(__p.first);
323     second = std::forward<_U2>(__p.second);
324     return *this;
325   }
326 
327 #  if _LIBCPP_STD_VER >= 23
328   _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair const& __p) const
329       noexcept(is_nothrow_copy_assignable_v<const first_type> && is_nothrow_copy_assignable_v<const second_type>)
330     requires(is_copy_assignable_v<const first_type> && is_copy_assignable_v<const second_type>)
331   {
332     first  = __p.first;
333     second = __p.second;
334     return *this;
335   }
336 
337   _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair&& __p) const
338       noexcept(is_nothrow_assignable_v<const first_type&, first_type> &&
339                is_nothrow_assignable_v<const second_type&, second_type>)
340     requires(is_assignable_v<const first_type&, first_type> && is_assignable_v<const second_type&, second_type>)
341   {
342     first  = std::forward<first_type>(__p.first);
343     second = std::forward<second_type>(__p.second);
344     return *this;
345   }
346 
347   template <class _U1, class _U2>
348   _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(const pair<_U1, _U2>& __p) const
349     requires(is_assignable_v<const first_type&, const _U1&> && is_assignable_v<const second_type&, const _U2&>)
350   {
351     first  = __p.first;
352     second = __p.second;
353     return *this;
354   }
355 
356   template <class _U1, class _U2>
357   _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair<_U1, _U2>&& __p) const
358     requires(is_assignable_v<const first_type&, _U1> && is_assignable_v<const second_type&, _U2>)
359   {
360     first  = std::forward<_U1>(__p.first);
361     second = std::forward<_U2>(__p.second);
362     return *this;
363   }
364 
365   template <__pair_like _PairLike>
366     requires(__different_from<_PairLike, pair> && !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
367              is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
368              is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>)
369   _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) {
370     first  = std::get<0>(std::forward<_PairLike>(__p));
371     second = std::get<1>(std::forward<_PairLike>(__p));
372     return *this;
373   }
374 
375   template <__pair_like _PairLike>
376     requires(__different_from<_PairLike, pair> && !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
377              is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
378              is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>)
379   _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const {
380     first  = std::get<0>(std::forward<_PairLike>(__p));
381     second = std::get<1>(std::forward<_PairLike>(__p));
382     return *this;
383   }
384 #  endif // _LIBCPP_STD_VER >= 23
385 
386   // Prior to C++23, we provide an approximation of constructors and assignment operators from
387   // pair-like types. This was historically provided as an extension.
388 #  if _LIBCPP_STD_VER < 23
389   // from std::tuple
390   template <
391       class _U1,
392       class _U2,
393       __enable_if_t< is_convertible<_U1 const&, _T1>::value && is_convertible<_U2 const&, _T2>::value >* = nullptr>
394   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(tuple<_U1, _U2> const& __p)
395       : first(std::get<0>(__p)), second(std::get<1>(__p)) {}
396 
397   template <
398       class _U1,
399       class _U2,
400       __enable_if_t< is_constructible<_T1, _U1 const&>::value && is_constructible<_T2, _U2 const&>::value &&
401                      !(is_convertible<_U1 const&, _T1>::value && is_convertible<_U2 const&, _T2>::value) >* = nullptr>
402   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(tuple<_U1, _U2> const& __p)
403       : first(std::get<0>(__p)), second(std::get<1>(__p)) {}
404 
405   template <class _U1,
406             class _U2,
407             __enable_if_t< is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value >* = nullptr>
408   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(tuple<_U1, _U2>&& __p)
409       : first(std::get<0>(std::move(__p))), second(std::get<1>(std::move(__p))) {}
410 
411   template <class _U1,
412             class _U2,
413             __enable_if_t< is_constructible<_T1, _U1>::value && is_constructible<_T2, _U2>::value &&
414                            !(is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value) >* = nullptr>
415   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(tuple<_U1, _U2>&& __p)
416       : first(std::get<0>(std::move(__p))), second(std::get<1>(std::move(__p))) {}
417 
418   template <
419       class _U1,
420       class _U2,
421       __enable_if_t< is_assignable<_T1&, _U1 const&>::value && is_assignable<_T2&, _U2 const&>::value >* = nullptr>
422   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2> const& __p) {
423     first  = std::get<0>(__p);
424     second = std::get<1>(__p);
425     return *this;
426   }
427 
428   template <class _U1,
429             class _U2,
430             __enable_if_t< is_assignable<_T1&, _U1&&>::value && is_assignable<_T2&, _U2&&>::value >* = nullptr>
431   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(tuple<_U1, _U2>&& __p) {
432     first  = std::get<0>(std::move(__p));
433     second = std::get<1>(std::move(__p));
434     return *this;
435   }
436 
437   // from std::array
438   template <
439       class _Up,
440       __enable_if_t< is_convertible<_Up const&, _T1>::value && is_convertible<_Up const&, _T2>::value >* = nullptr>
441   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(array<_Up, 2> const& __p) : first(__p[0]), second(__p[1]) {}
442 
443   template <
444       class _Up,
445       __enable_if_t< is_constructible<_T1, _Up const&>::value && is_constructible<_T2, _Up const&>::value &&
446                      !(is_convertible<_Up const&, _T1>::value && is_convertible<_Up const&, _T2>::value) >* = nullptr>
447   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(array<_Up, 2> const& __p)
448       : first(__p[0]), second(__p[1]) {}
449 
450   template <class _Up, __enable_if_t< is_convertible<_Up, _T1>::value && is_convertible<_Up, _T2>::value >* = nullptr>
451   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair(array<_Up, 2>&& __p)
452       : first(std::move(__p)[0]), second(std::move(__p)[1]) {}
453 
454   template <class _Up,
455             __enable_if_t< is_constructible<_T1, _Up>::value && is_constructible<_T2, _Up>::value &&
456                            !(is_convertible<_Up, _T1>::value && is_convertible<_Up, _T2>::value) >* = nullptr>
457   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit pair(array<_Up, 2>&& __p)
458       : first(std::move(__p)[0]), second(std::move(__p)[1]) {}
459 
460   template <
461       class _Up,
462       __enable_if_t< is_assignable<_T1&, _Up const&>::value && is_assignable<_T2&, _Up const&>::value >* = nullptr>
463   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2> const& __p) {
464     first  = std::get<0>(__p);
465     second = std::get<1>(__p);
466     return *this;
467   }
468 
469   template <class _Up, __enable_if_t< is_assignable<_T1&, _Up>::value && is_assignable<_T2&, _Up>::value >* = nullptr>
470   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair& operator=(array<_Up, 2>&& __p) {
471     first  = std::get<0>(std::move(__p));
472     second = std::get<1>(std::move(__p));
473     return *this;
474   }
475 #  endif // _LIBCPP_STD_VER < 23
476 #endif   // _LIBCPP_CXX03_LANG
477 
478   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(pair& __p)
479       _NOEXCEPT_(__is_nothrow_swappable<first_type>::value&& __is_nothrow_swappable<second_type>::value) {
480     using std::swap;
481     swap(first, __p.first);
482     swap(second, __p.second);
483   }
484 
485 #if _LIBCPP_STD_VER >= 23
486   _LIBCPP_HIDE_FROM_ABI constexpr void swap(const pair& __p) const
487       noexcept(__is_nothrow_swappable<const first_type>::value && __is_nothrow_swappable<const second_type>::value) {
488     using std::swap;
489     swap(first, __p.first);
490     swap(second, __p.second);
491   }
492 #endif
493 
494 private:
495 #ifndef _LIBCPP_CXX03_LANG
496   template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
497   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
498   pair(piecewise_construct_t,
499        tuple<_Args1...>& __first_args,
500        tuple<_Args2...>& __second_args,
501        __tuple_indices<_I1...>,
502        __tuple_indices<_I2...>);
503 #endif
504 };
505 
506 #if _LIBCPP_STD_VER >= 17
507 template <class _T1, class _T2>
508 pair(_T1, _T2) -> pair<_T1, _T2>;
509 #endif
510 
511 // [pairs.spec], specialized algorithms
512 
513 template <class _T1, class _T2, class _U1, class _U2>
514 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
515 operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
516   return __x.first == __y.first && __x.second == __y.second;
517 }
518 
519 #if _LIBCPP_STD_VER >= 20
520 
521 template <class _T1, class _T2, class _U1, class _U2>
522 _LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t< __synth_three_way_result<_T1, _U1>,
523                                                               __synth_three_way_result<_T2, _U2> >
524 operator<=>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
525   if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) {
526     return __c;
527   }
528   return std::__synth_three_way(__x.second, __y.second);
529 }
530 
531 #else // _LIBCPP_STD_VER >= 20
532 
533 template <class _T1, class _T2, class _U1, class _U2>
534 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
535 operator!=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
536   return !(__x == __y);
537 }
538 
539 template <class _T1, class _T2, class _U1, class _U2>
540 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
541 operator<(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
542   return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
543 }
544 
545 template <class _T1, class _T2, class _U1, class _U2>
546 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
547 operator>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
548   return __y < __x;
549 }
550 
551 template <class _T1, class _T2, class _U1, class _U2>
552 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
553 operator>=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
554   return !(__x < __y);
555 }
556 
557 template <class _T1, class _T2, class _U1, class _U2>
558 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
559 operator<=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
560   return !(__y < __x);
561 }
562 
563 #endif // _LIBCPP_STD_VER >= 20
564 
565 #if _LIBCPP_STD_VER >= 23
566 template <class _T1, class _T2, class _U1, class _U2, template <class> class _TQual, template <class> class _UQual>
567   requires requires {
568     typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
569   }
570 struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> {
571   using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
572 };
573 
574 template <class _T1, class _T2, class _U1, class _U2>
575   requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
576 struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> {
577   using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>;
578 };
579 #endif // _LIBCPP_STD_VER >= 23
580 
581 template <class _T1, class _T2, __enable_if_t<__is_swappable<_T1>::value && __is_swappable<_T2>::value, int> = 0>
582 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
583     _NOEXCEPT_((__is_nothrow_swappable<_T1>::value && __is_nothrow_swappable<_T2>::value)) {
584   __x.swap(__y);
585 }
586 
587 #if _LIBCPP_STD_VER >= 23
588 template <class _T1, class _T2>
589   requires(__is_swappable<const _T1>::value && __is_swappable<const _T2>::value)
590 _LIBCPP_HIDE_FROM_ABI constexpr void
591 swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x.swap(__y))) {
592   __x.swap(__y);
593 }
594 #endif
595 
596 template <class _T1, class _T2>
597 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
598     pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
599     make_pair(_T1&& __t1, _T2&& __t2) {
600   return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>(
601       std::forward<_T1>(__t1), std::forward<_T2>(__t2));
602 }
603 
604 template <class _T1, class _T2>
605 struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > : public integral_constant<size_t, 2> {};
606 
607 template <size_t _Ip, class _T1, class _T2>
608 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> > {
609   static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
610 };
611 
612 template <class _T1, class _T2>
613 struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > {
614   using type _LIBCPP_NODEBUG = _T1;
615 };
616 
617 template <class _T1, class _T2>
618 struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > {
619   using type _LIBCPP_NODEBUG = _T2;
620 };
621 
622 template <size_t _Ip>
623 struct __get_pair;
624 
625 template <>
626 struct __get_pair<0> {
627   template <class _T1, class _T2>
628   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
629     return __p.first;
630   }
631 
632   template <class _T1, class _T2>
633   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T1& get(const pair<_T1, _T2>& __p) _NOEXCEPT {
634     return __p.first;
635   }
636 
637   template <class _T1, class _T2>
638   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
639     return std::forward<_T1>(__p.first);
640   }
641 
642   template <class _T1, class _T2>
643   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T1&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
644     return std::forward<const _T1>(__p.first);
645   }
646 };
647 
648 template <>
649 struct __get_pair<1> {
650   template <class _T1, class _T2>
651   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT {
652     return __p.second;
653   }
654 
655   template <class _T1, class _T2>
656   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T2& get(const pair<_T1, _T2>& __p) _NOEXCEPT {
657     return __p.second;
658   }
659 
660   template <class _T1, class _T2>
661   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
662     return std::forward<_T2>(__p.second);
663   }
664 
665   template <class _T1, class _T2>
666   static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _T2&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
667     return std::forward<const _T2>(__p.second);
668   }
669 };
670 
671 template <size_t _Ip, class _T1, class _T2>
672 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
673 get(pair<_T1, _T2>& __p) _NOEXCEPT {
674   return __get_pair<_Ip>::get(__p);
675 }
676 
677 template <size_t _Ip, class _T1, class _T2>
678 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
679 get(const pair<_T1, _T2>& __p) _NOEXCEPT {
680   return __get_pair<_Ip>::get(__p);
681 }
682 
683 template <size_t _Ip, class _T1, class _T2>
684 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
685 get(pair<_T1, _T2>&& __p) _NOEXCEPT {
686   return __get_pair<_Ip>::get(std::move(__p));
687 }
688 
689 template <size_t _Ip, class _T1, class _T2>
690 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
691 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
692   return __get_pair<_Ip>::get(std::move(__p));
693 }
694 
695 #if _LIBCPP_STD_VER >= 14
696 template <class _T1, class _T2>
697 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
698   return __get_pair<0>::get(__p);
699 }
700 
701 template <class _T1, class _T2>
702 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
703   return __get_pair<0>::get(__p);
704 }
705 
706 template <class _T1, class _T2>
707 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
708   return __get_pair<0>::get(std::move(__p));
709 }
710 
711 template <class _T1, class _T2>
712 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) _NOEXCEPT {
713   return __get_pair<0>::get(std::move(__p));
714 }
715 
716 template <class _T1, class _T2>
717 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T2, _T1>& __p) _NOEXCEPT {
718   return __get_pair<1>::get(__p);
719 }
720 
721 template <class _T1, class _T2>
722 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T2, _T1> const& __p) _NOEXCEPT {
723   return __get_pair<1>::get(__p);
724 }
725 
726 template <class _T1, class _T2>
727 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T2, _T1>&& __p) _NOEXCEPT {
728   return __get_pair<1>::get(std::move(__p));
729 }
730 
731 template <class _T1, class _T2>
732 inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T2, _T1> const&& __p) _NOEXCEPT {
733   return __get_pair<1>::get(std::move(__p));
734 }
735 
736 #endif // _LIBCPP_STD_VER >= 14
737 
738 _LIBCPP_END_NAMESPACE_STD
739 
740 _LIBCPP_POP_MACROS
741 
742 #endif // _LIBCPP___UTILITY_PAIR_H
743