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