• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <__config>
15 #include <__functional/unwrap_ref.h>
16 #include <__fwd/get.h>
17 #include <__fwd/tuple.h>
18 #include <__tuple/sfinae_helpers.h>
19 #include <__tuple/tuple_element.h>
20 #include <__tuple/tuple_indices.h>
21 #include <__tuple/tuple_size.h>
22 #include <__type_traits/common_reference.h>
23 #include <__type_traits/common_type.h>
24 #include <__type_traits/conditional.h>
25 #include <__type_traits/decay.h>
26 #include <__type_traits/is_assignable.h>
27 #include <__type_traits/is_constructible.h>
28 #include <__type_traits/is_convertible.h>
29 #include <__type_traits/is_copy_assignable.h>
30 #include <__type_traits/is_default_constructible.h>
31 #include <__type_traits/is_implicitly_default_constructible.h>
32 #include <__type_traits/is_move_assignable.h>
33 #include <__type_traits/is_nothrow_assignable.h>
34 #include <__type_traits/is_nothrow_constructible.h>
35 #include <__type_traits/is_nothrow_copy_assignable.h>
36 #include <__type_traits/is_nothrow_copy_constructible.h>
37 #include <__type_traits/is_nothrow_default_constructible.h>
38 #include <__type_traits/is_nothrow_move_assignable.h>
39 #include <__type_traits/is_same.h>
40 #include <__type_traits/is_swappable.h>
41 #include <__type_traits/nat.h>
42 #include <__utility/forward.h>
43 #include <__utility/move.h>
44 #include <__utility/piecewise_construct.h>
45 #include <cstddef>
46 
47 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
48 #  pragma GCC system_header
49 #endif
50 
51 _LIBCPP_BEGIN_NAMESPACE_STD
52 
53 template <class, class>
54 struct __non_trivially_copyable_base {
55   _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
__non_trivially_copyable_base__non_trivially_copyable_base56   __non_trivially_copyable_base() _NOEXCEPT {}
57   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
__non_trivially_copyable_base__non_trivially_copyable_base58   __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
59 };
60 
61 template <class _T1, class _T2>
62 struct _LIBCPP_TEMPLATE_VIS pair
63 #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
64 : private __non_trivially_copyable_base<_T1, _T2>
65 #endif
66 {
67     using first_type = _T1;
68     using second_type = _T2;
69 
70     _T1 first;
71     _T2 second;
72 
73     _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
74     _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;
75 
76 #ifdef _LIBCPP_CXX03_LANG
77     _LIBCPP_HIDE_FROM_ABI
pairpair78     pair() : first(), second() {}
79 
80     _LIBCPP_HIDE_FROM_ABI
pairpair81     pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
82 
83     template <class _U1, class _U2>
84     _LIBCPP_HIDE_FROM_ABI
pairpair85     pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
86 
87     _LIBCPP_HIDE_FROM_ABI
88     pair& operator=(pair const& __p) {
89         first = __p.first;
90         second = __p.second;
91         return *this;
92     }
93 #else
94     struct _CheckArgs {
95       template <int&...>
__enable_explicit_defaultpair::_CheckArgs96       static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() {
97           return is_default_constructible<_T1>::value
98               && is_default_constructible<_T2>::value
99               && !__enable_implicit_default<>();
100       }
101 
102       template <int&...>
__enable_implicit_defaultpair::_CheckArgs103       static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() {
104           return __is_implicitly_default_constructible<_T1>::value
105               && __is_implicitly_default_constructible<_T2>::value;
106       }
107 
108       template <class _U1, class _U2>
__is_pair_constructiblepair::_CheckArgs109       static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() {
110           return is_constructible<first_type, _U1>::value
111               && is_constructible<second_type, _U2>::value;
112       }
113 
114       template <class _U1, class _U2>
__is_implicitpair::_CheckArgs115       static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() {
116           return is_convertible<_U1, first_type>::value
117               && is_convertible<_U2, second_type>::value;
118       }
119 
120       template <class _U1, class _U2>
__enable_explicitpair::_CheckArgs121       static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() {
122           return __is_pair_constructible<_U1, _U2>() && !__is_implicit<_U1, _U2>();
123       }
124 
125       template <class _U1, class _U2>
__enable_implicitpair::_CheckArgs126       static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() {
127           return __is_pair_constructible<_U1, _U2>() && __is_implicit<_U1, _U2>();
128       }
129     };
130 
131     template <bool _MaybeEnable>
132     using _CheckArgsDep _LIBCPP_NODEBUG = typename conditional<
133       _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
134 
135     struct _CheckTupleLikeConstructor {
136         template <class _Tuple>
__enable_implicitpair::_CheckTupleLikeConstructor137         static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() {
138             return __tuple_convertible<_Tuple, pair>::value;
139         }
140 
141         template <class _Tuple>
__enable_explicitpair::_CheckTupleLikeConstructor142         static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() {
143             return __tuple_constructible<_Tuple, pair>::value
144                && !__tuple_convertible<_Tuple, pair>::value;
145         }
146 
147         template <class _Tuple>
__enable_assignpair::_CheckTupleLikeConstructor148         static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_assign() {
149             return __tuple_assignable<_Tuple, pair>::value;
150         }
151     };
152 
153     template <class _Tuple>
154     using _CheckTLC _LIBCPP_NODEBUG = __conditional_t<
155         __tuple_like_with_size<_Tuple, 2>::value
156             && !is_same<__decay_t<_Tuple>, pair>::value,
157         _CheckTupleLikeConstructor,
158         __check_tuple_constructor_fail
159     >;
160 
161     template<bool _Dummy = true, typename enable_if<
162             _CheckArgsDep<_Dummy>::__enable_explicit_default()
163     >::type* = nullptr>
164     explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
pairpair165     pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
166                       is_nothrow_default_constructible<second_type>::value)
167         : first(), second() {}
168 
169     template<bool _Dummy = true, typename enable_if<
170             _CheckArgsDep<_Dummy>::__enable_implicit_default()
171     >::type* = nullptr>
172     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
pairpair173     pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value &&
174                       is_nothrow_default_constructible<second_type>::value)
175         : first(), second() {}
176 
177     template <bool _Dummy = true, typename enable_if<
178              _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>()
179     >::type* = nullptr>
180     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pairpair181     explicit pair(_T1 const& __t1, _T2 const& __t2)
182         _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
183                    is_nothrow_copy_constructible<second_type>::value)
184         : first(__t1), second(__t2) {}
185 
186     template<bool _Dummy = true, typename enable_if<
187             _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>()
188     >::type* = nullptr>
189     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pairpair190     pair(_T1 const& __t1, _T2 const& __t2)
191         _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
192                    is_nothrow_copy_constructible<second_type>::value)
193         : first(__t1), second(__t2) {}
194 
195     template <
196 #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
197         class _U1 = _T1, class _U2 = _T2,
198 #else
199         class _U1, class _U2,
200 #endif
201         typename enable_if<_CheckArgs::template __enable_explicit<_U1, _U2>()>::type* = nullptr
202     >
203     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pairpair204     explicit 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     template <
210 #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
211         class _U1 = _T1, class _U2 = _T2,
212 #else
213         class _U1, class _U2,
214 #endif
215         typename enable_if<_CheckArgs::template __enable_implicit<_U1, _U2>()>::type* = nullptr
216     >
217     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pairpair218     pair(_U1&& __u1, _U2&& __u2)
219         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value &&
220                     is_nothrow_constructible<second_type, _U2>::value))
221         : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {}
222 
223 #if _LIBCPP_STD_VER >= 23
224     template<class _U1, class _U2, __enable_if_t<
225             _CheckArgs::template __is_pair_constructible<_U1&, _U2&>()
226     >* = nullptr>
227     _LIBCPP_HIDE_FROM_ABI constexpr
pairpair228     explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>()) pair(pair<_U1, _U2>& __p)
229         noexcept((is_nothrow_constructible<first_type, _U1&>::value &&
230                   is_nothrow_constructible<second_type, _U2&>::value))
231         : first(__p.first), second(__p.second) {}
232 #endif
233 
234     template<class _U1, class _U2, typename enable_if<
235             _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>()
236     >::type* = nullptr>
237     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pairpair238     explicit pair(pair<_U1, _U2> const& __p)
239         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
240                     is_nothrow_constructible<second_type, _U2 const&>::value))
241         : first(__p.first), second(__p.second) {}
242 
243     template<class _U1, class _U2, typename enable_if<
244             _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>()
245     >::type* = nullptr>
246     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pairpair247     pair(pair<_U1, _U2> const& __p)
248         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value &&
249                     is_nothrow_constructible<second_type, _U2 const&>::value))
250         : first(__p.first), second(__p.second) {}
251 
252     template<class _U1, class _U2, typename enable_if<
253             _CheckArgs::template __enable_explicit<_U1, _U2>()
254     >::type* = nullptr>
255     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pairpair256     explicit pair(pair<_U1, _U2>&&__p)
257         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
258                     is_nothrow_constructible<second_type, _U2&&>::value))
259         : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
260 
261     template<class _U1, class _U2, typename enable_if<
262             _CheckArgs::template __enable_implicit<_U1, _U2>()
263     >::type* = nullptr>
264     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pairpair265     pair(pair<_U1, _U2>&& __p)
266         _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value &&
267                     is_nothrow_constructible<second_type, _U2&&>::value))
268         : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}
269 
270 #if _LIBCPP_STD_VER >= 23
271     template<class _U1, class _U2, __enable_if_t<
272             _CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>()
273     >* = nullptr>
274     _LIBCPP_HIDE_FROM_ABI constexpr
275     explicit(!_CheckArgs::template __is_implicit<const _U1&&, const _U2&&>())
pairpair276     pair(const pair<_U1, _U2>&& __p)
277         noexcept(is_nothrow_constructible<first_type, const _U1&&>::value &&
278                  is_nothrow_constructible<second_type, const _U2&&>::value)
279         : first(std::move(__p.first)), second(std::move(__p.second)) {}
280 #endif
281 
282     template<class _Tuple, typename enable_if<
283             _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>()
284     >::type* = nullptr>
285     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pairpair286     explicit pair(_Tuple&& __p)
287         : first(std::get<0>(std::forward<_Tuple>(__p))),
288           second(std::get<1>(std::forward<_Tuple>(__p))) {}
289 
290     template<class _Tuple, typename enable_if<
291             _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>()
292     >::type* = nullptr>
293     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pairpair294     pair(_Tuple&& __p)
295         : first(std::get<0>(std::forward<_Tuple>(__p))),
296           second(std::get<1>(std::forward<_Tuple>(__p))) {}
297 
298     template <class... _Args1, class... _Args2>
299     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
pairpair300     pair(piecewise_construct_t __pc,
301          tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
302         _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
303                     is_nothrow_constructible<second_type, _Args2...>::value))
304         : pair(__pc, __first_args, __second_args,
305                 typename __make_tuple_indices<sizeof...(_Args1)>::type(),
306                 typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
307 
308     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
309     pair& operator=(__conditional_t<
310                         is_copy_assignable<first_type>::value &&
311                         is_copy_assignable<second_type>::value,
312                     pair, __nat> const& __p)
_NOEXCEPT_pair313         _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
314                    is_nothrow_copy_assignable<second_type>::value)
315     {
316         first = __p.first;
317         second = __p.second;
318         return *this;
319     }
320 
321     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
322     pair& operator=(__conditional_t<
323                         is_move_assignable<first_type>::value &&
324                         is_move_assignable<second_type>::value,
325                     pair, __nat>&& __p)
_NOEXCEPT_pair326         _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
327                    is_nothrow_move_assignable<second_type>::value)
328     {
329         first = std::forward<first_type>(__p.first);
330         second = std::forward<second_type>(__p.second);
331         return *this;
332     }
333 
334 #if _LIBCPP_STD_VER >= 23
335     _LIBCPP_HIDE_FROM_ABI constexpr
336     const pair& operator=(pair const& __p) const
noexceptpair337       noexcept(is_nothrow_copy_assignable_v<const first_type> &&
338                is_nothrow_copy_assignable_v<const second_type>)
339       requires(is_copy_assignable_v<const first_type> &&
340                is_copy_assignable_v<const second_type>) {
341         first = __p.first;
342         second = __p.second;
343         return *this;
344     }
345 
346     _LIBCPP_HIDE_FROM_ABI constexpr
347     const pair& operator=(pair&& __p) const
noexceptpair348       noexcept(is_nothrow_assignable_v<const first_type&, first_type> &&
349                is_nothrow_assignable_v<const second_type&, second_type>)
350       requires(is_assignable_v<const first_type&, first_type> &&
351                is_assignable_v<const second_type&, second_type>) {
352         first = std::forward<first_type>(__p.first);
353         second = std::forward<second_type>(__p.second);
354         return *this;
355     }
356 
357     template<class _U1, class _U2>
358     _LIBCPP_HIDE_FROM_ABI constexpr
359     const pair& operator=(const pair<_U1, _U2>& __p) const
requirespair360       requires(is_assignable_v<const first_type&, const _U1&> &&
361                is_assignable_v<const second_type&, const _U2&>) {
362         first = __p.first;
363         second = __p.second;
364         return *this;
365     }
366 
367     template<class _U1, class _U2>
368     _LIBCPP_HIDE_FROM_ABI constexpr
369     const pair& operator=(pair<_U1, _U2>&& __p) const
requirespair370       requires(is_assignable_v<const first_type&, _U1> &&
371                is_assignable_v<const second_type&, _U2>) {
372         first = std::forward<_U1>(__p.first);
373         second = std::forward<_U2>(__p.second);
374         return *this;
375     }
376 #endif // _LIBCPP_STD_VER >= 23
377 
378     template <class _Tuple, typename enable_if<
379             _CheckTLC<_Tuple>::template __enable_assign<_Tuple>()
380      >::type* = nullptr>
381     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
382     pair& operator=(_Tuple&& __p) {
383         first = std::get<0>(std::forward<_Tuple>(__p));
384         second = std::get<1>(std::forward<_Tuple>(__p));
385         return *this;
386     }
387 #endif // _LIBCPP_CXX03_LANG
388 
389     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
390     void
swappair391     swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
392                                __is_nothrow_swappable<second_type>::value)
393     {
394         using std::swap;
395         swap(first,  __p.first);
396         swap(second, __p.second);
397     }
398 
399 #if _LIBCPP_STD_VER >= 23
400     _LIBCPP_HIDE_FROM_ABI constexpr
swappair401     void swap(const pair& __p) const
402         noexcept(__is_nothrow_swappable<const first_type>::value &&
403                  __is_nothrow_swappable<const second_type>::value)
404     {
405         using std::swap;
406         swap(first,  __p.first);
407         swap(second, __p.second);
408     }
409 #endif
410 private:
411 
412 #ifndef _LIBCPP_CXX03_LANG
413     template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
414     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
415     pair(piecewise_construct_t,
416          tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
417          __tuple_indices<_I1...>, __tuple_indices<_I2...>);
418 #endif
419 };
420 
421 #if _LIBCPP_STD_VER >= 17
422 template<class _T1, class _T2>
423 pair(_T1, _T2) -> pair<_T1, _T2>;
424 #endif
425 
426 // [pairs.spec], specialized algorithms
427 
428 template <class _T1, class _T2, class _U1, class _U2>
429 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
430 bool
431 operator==(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
432 {
433     return __x.first == __y.first && __x.second == __y.second;
434 }
435 
436 #if _LIBCPP_STD_VER >= 20
437 
438 template <class _T1, class _T2, class _U1, class _U2>
439 _LIBCPP_HIDE_FROM_ABI constexpr
440 common_comparison_category_t<
441         __synth_three_way_result<_T1, _U1>,
442         __synth_three_way_result<_T2, _U2> >
443 operator<=>(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
444 {
445     if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) {
446       return __c;
447     }
448     return std::__synth_three_way(__x.second, __y.second);
449 }
450 
451 #else // _LIBCPP_STD_VER >= 20
452 
453 template <class _T1, class _T2, class _U1, class _U2>
454 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
455 bool
456 operator!=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
457 {
458     return !(__x == __y);
459 }
460 
461 template <class _T1, class _T2, class _U1, class _U2>
462 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
463 bool
464 operator< (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
465 {
466     return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
467 }
468 
469 template <class _T1, class _T2, class _U1, class _U2>
470 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
471 bool
472 operator> (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
473 {
474     return __y < __x;
475 }
476 
477 template <class _T1, class _T2, class _U1, class _U2>
478 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
479 bool
480 operator>=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
481 {
482     return !(__x < __y);
483 }
484 
485 template <class _T1, class _T2, class _U1, class _U2>
486 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
487 bool
488 operator<=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
489 {
490     return !(__y < __x);
491 }
492 
493 #endif // _LIBCPP_STD_VER >= 20
494 
495 #if _LIBCPP_STD_VER >= 23
496 template <class _T1, class _T2, class _U1, class _U2, template<class> class _TQual, template<class> class _UQual>
497     requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
498                                       common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
499 struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> {
500     using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
501                       common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
502 };
503 
504 template <class _T1, class _T2, class _U1, class _U2>
505     requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
506 struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> {
507     using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>;
508 };
509 #endif // _LIBCPP_STD_VER >= 23
510 
511 template <class _T1, class _T2>
512 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
513 typename enable_if
514 <
515     __is_swappable<_T1>::value &&
516     __is_swappable<_T2>::value,
517     void
518 >::type
519 swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
520                      _NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&
521                                  __is_nothrow_swappable<_T2>::value))
522 {
523     __x.swap(__y);
524 }
525 
526 #if _LIBCPP_STD_VER >= 23
527 template <class _T1, class _T2>
528   requires (__is_swappable<const _T1>::value &&
529             __is_swappable<const _T2>::value)
530 _LIBCPP_HIDE_FROM_ABI constexpr
531 void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
532     noexcept(noexcept(__x.swap(__y)))
533 {
534     __x.swap(__y);
535 }
536 #endif
537 
538 template <class _T1, class _T2>
539 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
540 pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
541 make_pair(_T1&& __t1, _T2&& __t2)
542 {
543     return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
544                (std::forward<_T1>(__t1), std::forward<_T2>(__t2));
545 }
546 
547 template <class _T1, class _T2>
548   struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
549     : public integral_constant<size_t, 2> {};
550 
551 template <size_t _Ip, class _T1, class _T2>
552 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
553 {
554     static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
555 };
556 
557 template <class _T1, class _T2>
558 struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
559 {
560     using type _LIBCPP_NODEBUG = _T1;
561 };
562 
563 template <class _T1, class _T2>
564 struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
565 {
566     using type _LIBCPP_NODEBUG = _T2;
567 };
568 
569 template <size_t _Ip> struct __get_pair;
570 
571 template <>
572 struct __get_pair<0>
573 {
574     template <class _T1, class _T2>
575     static
576     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
577     _T1&
578     get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
579 
580     template <class _T1, class _T2>
581     static
582     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
583     const _T1&
584     get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
585 
586     template <class _T1, class _T2>
587     static
588     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
589     _T1&&
590     get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T1>(__p.first);}
591 
592     template <class _T1, class _T2>
593     static
594     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
595     const _T1&&
596     get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T1>(__p.first);}
597 };
598 
599 template <>
600 struct __get_pair<1>
601 {
602     template <class _T1, class _T2>
603     static
604     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
605     _T2&
606     get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
607 
608     template <class _T1, class _T2>
609     static
610     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
611     const _T2&
612     get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
613 
614     template <class _T1, class _T2>
615     static
616     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
617     _T2&&
618     get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T2>(__p.second);}
619 
620     template <class _T1, class _T2>
621     static
622     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
623     const _T2&&
624     get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T2>(__p.second);}
625 };
626 
627 template <size_t _Ip, class _T1, class _T2>
628 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
629 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
630 get(pair<_T1, _T2>& __p) _NOEXCEPT
631 {
632     return __get_pair<_Ip>::get(__p);
633 }
634 
635 template <size_t _Ip, class _T1, class _T2>
636 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
637 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
638 get(const pair<_T1, _T2>& __p) _NOEXCEPT
639 {
640     return __get_pair<_Ip>::get(__p);
641 }
642 
643 template <size_t _Ip, class _T1, class _T2>
644 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
645 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
646 get(pair<_T1, _T2>&& __p) _NOEXCEPT
647 {
648     return __get_pair<_Ip>::get(std::move(__p));
649 }
650 
651 template <size_t _Ip, class _T1, class _T2>
652 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
653 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
654 get(const pair<_T1, _T2>&& __p) _NOEXCEPT
655 {
656     return __get_pair<_Ip>::get(std::move(__p));
657 }
658 
659 #if _LIBCPP_STD_VER >= 14
660 template <class _T1, class _T2>
661 inline _LIBCPP_HIDE_FROM_ABI
662 constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
663 {
664     return __get_pair<0>::get(__p);
665 }
666 
667 template <class _T1, class _T2>
668 inline _LIBCPP_HIDE_FROM_ABI
669 constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
670 {
671     return __get_pair<0>::get(__p);
672 }
673 
674 template <class _T1, class _T2>
675 inline _LIBCPP_HIDE_FROM_ABI
676 constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
677 {
678     return __get_pair<0>::get(std::move(__p));
679 }
680 
681 template <class _T1, class _T2>
682 inline _LIBCPP_HIDE_FROM_ABI
683 constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT
684 {
685     return __get_pair<0>::get(std::move(__p));
686 }
687 
688 template <class _T1, class _T2>
689 inline _LIBCPP_HIDE_FROM_ABI
690 constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
691 {
692     return __get_pair<1>::get(__p);
693 }
694 
695 template <class _T1, class _T2>
696 inline _LIBCPP_HIDE_FROM_ABI
697 constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
698 {
699     return __get_pair<1>::get(__p);
700 }
701 
702 template <class _T1, class _T2>
703 inline _LIBCPP_HIDE_FROM_ABI
704 constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
705 {
706     return __get_pair<1>::get(std::move(__p));
707 }
708 
709 template <class _T1, class _T2>
710 inline _LIBCPP_HIDE_FROM_ABI
711 constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT
712 {
713     return __get_pair<1>::get(std::move(__p));
714 }
715 
716 #endif // _LIBCPP_STD_VER >= 14
717 
718 _LIBCPP_END_NAMESPACE_STD
719 
720 #endif // _LIBCPP___UTILITY_PAIR_H
721