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