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