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