[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / libcxx / include / __utility / pair.h
blob85d2f21af2420f3c403bddb328f020fe1ace886c
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 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___UTILITY_PAIR_H
10 #define _LIBCPP___UTILITY_PAIR_H
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>
55 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
56 # pragma GCC system_header
57 #endif
59 _LIBCPP_PUSH_MACROS
60 #include <__undef_macros>
62 _LIBCPP_BEGIN_NAMESPACE_STD
64 template <class, class>
65 struct __non_trivially_copyable_base {
66 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI
67 __non_trivially_copyable_base() _NOEXCEPT {}
68 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI
69 __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
72 #if _LIBCPP_STD_VER >= 23
73 template <class _Tp>
74 struct __is_specialization_of_subrange : false_type {};
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
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
86 using first_type = _T1;
87 using second_type = _T2;
89 _T1 first;
90 _T2 second;
92 _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
93 _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;
95 #ifdef _LIBCPP_CXX03_LANG
96 _LIBCPP_HIDE_FROM_ABI
97 pair() : first(), second() {}
99 _LIBCPP_HIDE_FROM_ABI
100 pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
102 template <class _U1, class _U2>
103 _LIBCPP_HIDE_FROM_ABI
104 pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
106 _LIBCPP_HIDE_FROM_ABI
107 pair& operator=(pair const& __p) {
108 first = __p.first;
109 second = __p.second;
110 return *this;
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
120 _LIBCPP_HIDE_FROM_ABI
121 pair& operator=(pair<_U1, _U2> const& __p) {
122 first = __p.first;
123 second = __p.second;
124 return *this;
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<>();
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;
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;
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;
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>();
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>();
164 template <bool _MaybeEnable>
165 using _CheckArgsDep _LIBCPP_NODEBUG = typename conditional<
166 _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type;
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() {}
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() {}
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) {}
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) {}
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
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)) {}
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
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)) {}
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
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) {}
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) {}
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)) {}
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)) {}
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
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, bool _Enable = tuple_size<remove_cvref_t<_PairLike>>::value == 2>
278 _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() {
279 if constexpr (tuple_size<remove_cvref_t<_PairLike>>::value == 2) {
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>;
283 return false;
286 template <__pair_like _PairLike>
287 requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike&&>()))> &&
288 is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike&&>()))>)
289 _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>())
290 pair(_PairLike&& __p)
291 : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {}
292 # endif
294 template <class... _Args1, class... _Args2>
295 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
296 pair(piecewise_construct_t __pc,
297 tuple<_Args1...> __first_args, tuple<_Args2...> __second_args)
298 _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value &&
299 is_nothrow_constructible<second_type, _Args2...>::value))
300 : pair(__pc, __first_args, __second_args,
301 typename __make_tuple_indices<sizeof...(_Args1)>::type(),
302 typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}
304 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
305 pair& operator=(__conditional_t<
306 is_copy_assignable<first_type>::value &&
307 is_copy_assignable<second_type>::value,
308 pair, __nat> const& __p)
309 _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
310 is_nothrow_copy_assignable<second_type>::value)
312 first = __p.first;
313 second = __p.second;
314 return *this;
317 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
318 pair& operator=(__conditional_t<
319 is_move_assignable<first_type>::value &&
320 is_move_assignable<second_type>::value,
321 pair, __nat>&& __p)
322 _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
323 is_nothrow_move_assignable<second_type>::value)
325 first = std::forward<first_type>(__p.first);
326 second = std::forward<second_type>(__p.second);
327 return *this;
330 template <class _U1, class _U2, __enable_if_t<
331 is_assignable<first_type&, _U1 const&>::value &&
332 is_assignable<second_type&, _U2 const&>::value
333 >* = nullptr>
334 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
335 pair& operator=(pair<_U1, _U2> const& __p) {
336 first = __p.first;
337 second = __p.second;
338 return *this;
341 template <class _U1, class _U2, __enable_if_t<
342 is_assignable<first_type&, _U1>::value &&
343 is_assignable<second_type&, _U2>::value
344 >* = nullptr>
345 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
346 pair& operator=(pair<_U1, _U2>&& __p) {
347 first = std::forward<_U1>(__p.first);
348 second = std::forward<_U2>(__p.second);
349 return *this;
352 # if _LIBCPP_STD_VER >= 23
353 _LIBCPP_HIDE_FROM_ABI constexpr
354 const pair& operator=(pair const& __p) const
355 noexcept(is_nothrow_copy_assignable_v<const first_type> &&
356 is_nothrow_copy_assignable_v<const second_type>)
357 requires(is_copy_assignable_v<const first_type> &&
358 is_copy_assignable_v<const second_type>) {
359 first = __p.first;
360 second = __p.second;
361 return *this;
364 _LIBCPP_HIDE_FROM_ABI constexpr
365 const pair& operator=(pair&& __p) const
366 noexcept(is_nothrow_assignable_v<const first_type&, first_type> &&
367 is_nothrow_assignable_v<const second_type&, second_type>)
368 requires(is_assignable_v<const first_type&, first_type> &&
369 is_assignable_v<const second_type&, second_type>) {
370 first = std::forward<first_type>(__p.first);
371 second = std::forward<second_type>(__p.second);
372 return *this;
375 template<class _U1, class _U2>
376 _LIBCPP_HIDE_FROM_ABI constexpr
377 const pair& operator=(const pair<_U1, _U2>& __p) const
378 requires(is_assignable_v<const first_type&, const _U1&> &&
379 is_assignable_v<const second_type&, const _U2&>) {
380 first = __p.first;
381 second = __p.second;
382 return *this;
385 template<class _U1, class _U2>
386 _LIBCPP_HIDE_FROM_ABI constexpr
387 const pair& operator=(pair<_U1, _U2>&& __p) const
388 requires(is_assignable_v<const first_type&, _U1> &&
389 is_assignable_v<const second_type&, _U2>) {
390 first = std::forward<_U1>(__p.first);
391 second = std::forward<_U2>(__p.second);
392 return *this;
395 template <__pair_like _PairLike>
396 requires(__different_from<_PairLike, pair> &&
397 !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
398 is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
399 is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>)
400 _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) {
401 first = std::get<0>(std::forward<_PairLike>(__p));
402 second = std::get<1>(std::forward<_PairLike>(__p));
403 return *this;
406 template <__pair_like _PairLike>
407 requires(__different_from<_PairLike, pair> &&
408 !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
409 is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
410 is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>)
411 _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const {
412 first = std::get<0>(std::forward<_PairLike>(__p));
413 second = std::get<1>(std::forward<_PairLike>(__p));
414 return *this;
416 # endif // _LIBCPP_STD_VER >= 23
418 // Prior to C++23, we provide an approximation of constructors and assignment operators from
419 // pair-like types. This was historically provided as an extension.
420 #if _LIBCPP_STD_VER < 23
421 // from std::tuple
422 template<class _U1, class _U2, __enable_if_t<
423 is_convertible<_U1 const&, _T1>::value &&
424 is_convertible<_U2 const&, _T2>::value
425 >* = nullptr>
426 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
427 pair(tuple<_U1, _U2> const& __p)
428 : first(std::get<0>(__p)),
429 second(std::get<1>(__p)) {}
431 template<class _U1, class _U2, __enable_if_t<
432 is_constructible<_T1, _U1 const&>::value &&
433 is_constructible<_T2, _U2 const&>::value &&
434 !(is_convertible<_U1 const&, _T1>::value &&
435 is_convertible<_U2 const&, _T2>::value)
436 >* = nullptr>
437 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
438 explicit
439 pair(tuple<_U1, _U2> const& __p)
440 : first(std::get<0>(__p)),
441 second(std::get<1>(__p)) {}
443 template<class _U1, class _U2, __enable_if_t<
444 is_convertible<_U1, _T1>::value &&
445 is_convertible<_U2, _T2>::value
446 >* = nullptr>
447 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
448 pair(tuple<_U1, _U2>&& __p)
449 : first(std::get<0>(std::move(__p))),
450 second(std::get<1>(std::move(__p))) {}
452 template<class _U1, class _U2, __enable_if_t<
453 is_constructible<_T1, _U1>::value &&
454 is_constructible<_T2, _U2>::value &&
455 !(is_convertible<_U1, _T1>::value &&
456 is_convertible<_U2, _T2>::value)
457 >* = nullptr>
458 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
459 explicit
460 pair(tuple<_U1, _U2>&& __p)
461 : first(std::get<0>(std::move(__p))),
462 second(std::get<1>(std::move(__p))) {}
465 template<class _U1, class _U2, __enable_if_t<
466 is_assignable<_T1&, _U1 const&>::value &&
467 is_assignable<_T2&, _U2 const&>::value
468 >* = nullptr>
469 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
470 pair& operator=(tuple<_U1, _U2> const& __p) {
471 first = std::get<0>(__p);
472 second = std::get<1>(__p);
473 return *this;
476 template<class _U1, class _U2, __enable_if_t<
477 is_assignable<_T1&, _U1&&>::value &&
478 is_assignable<_T2&, _U2&&>::value
479 >* = nullptr>
480 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
481 pair& operator=(tuple<_U1, _U2>&& __p) {
482 first = std::get<0>(std::move(__p));
483 second = std::get<1>(std::move(__p));
484 return *this;
487 // from std::array
488 template<class _Up, __enable_if_t<
489 is_convertible<_Up const&, _T1>::value &&
490 is_convertible<_Up const&, _T2>::value
491 >* = nullptr>
492 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
493 pair(array<_Up, 2> const& __p)
494 : first(__p[0]),
495 second(__p[1]) {}
497 template<class _Up, __enable_if_t<
498 is_constructible<_T1, _Up const&>::value &&
499 is_constructible<_T2, _Up const&>::value &&
500 !(is_convertible<_Up const&, _T1>::value &&
501 is_convertible<_Up const&, _T2>::value)
502 >* = nullptr>
503 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
504 explicit
505 pair(array<_Up, 2> const& __p)
506 : first(__p[0]),
507 second(__p[1]) {}
509 template<class _Up, __enable_if_t<
510 is_convertible<_Up, _T1>::value &&
511 is_convertible<_Up, _T2>::value
512 >* = nullptr>
513 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
514 pair(array<_Up, 2>&& __p)
515 : first(std::move(__p)[0]),
516 second(std::move(__p)[1]) {}
518 template<class _Up, __enable_if_t<
519 is_constructible<_T1, _Up>::value &&
520 is_constructible<_T2, _Up>::value &&
521 !(is_convertible<_Up, _T1>::value &&
522 is_convertible<_Up, _T2>::value)
523 >* = nullptr>
524 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
525 explicit
526 pair(array<_Up, 2>&& __p)
527 : first(std::move(__p)[0]),
528 second(std::move(__p)[1]) {}
531 template<class _Up, __enable_if_t<
532 is_assignable<_T1&, _Up const&>::value &&
533 is_assignable<_T2&, _Up const&>::value
534 >* = nullptr>
535 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
536 pair& operator=(array<_Up, 2> const& __p) {
537 first = std::get<0>(__p);
538 second = std::get<1>(__p);
539 return *this;
542 template<class _Up, __enable_if_t<
543 is_assignable<_T1&, _Up>::value &&
544 is_assignable<_T2&, _Up>::value
545 >* = nullptr>
546 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
547 pair& operator=(array<_Up, 2>&& __p) {
548 first = std::get<0>(std::move(__p));
549 second = std::get<1>(std::move(__p));
550 return *this;
552 #endif // _LIBCPP_STD_VER < 23
553 #endif // _LIBCPP_CXX03_LANG
555 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
556 void
557 swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
558 __is_nothrow_swappable<second_type>::value)
560 using std::swap;
561 swap(first, __p.first);
562 swap(second, __p.second);
565 #if _LIBCPP_STD_VER >= 23
566 _LIBCPP_HIDE_FROM_ABI constexpr
567 void swap(const pair& __p) const
568 noexcept(__is_nothrow_swappable<const first_type>::value &&
569 __is_nothrow_swappable<const second_type>::value)
571 using std::swap;
572 swap(first, __p.first);
573 swap(second, __p.second);
575 #endif
576 private:
578 #ifndef _LIBCPP_CXX03_LANG
579 template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
580 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
581 pair(piecewise_construct_t,
582 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
583 __tuple_indices<_I1...>, __tuple_indices<_I2...>);
584 #endif
587 #if _LIBCPP_STD_VER >= 17
588 template<class _T1, class _T2>
589 pair(_T1, _T2) -> pair<_T1, _T2>;
590 #endif
592 // [pairs.spec], specialized algorithms
594 template <class _T1, class _T2, class _U1, class _U2>
595 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
596 bool
597 operator==(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
599 return __x.first == __y.first && __x.second == __y.second;
602 #if _LIBCPP_STD_VER >= 20
604 template <class _T1, class _T2, class _U1, class _U2>
605 _LIBCPP_HIDE_FROM_ABI constexpr
606 common_comparison_category_t<
607 __synth_three_way_result<_T1, _U1>,
608 __synth_three_way_result<_T2, _U2> >
609 operator<=>(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
611 if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) {
612 return __c;
614 return std::__synth_three_way(__x.second, __y.second);
617 #else // _LIBCPP_STD_VER >= 20
619 template <class _T1, class _T2, class _U1, class _U2>
620 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
621 bool
622 operator!=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
624 return !(__x == __y);
627 template <class _T1, class _T2, class _U1, class _U2>
628 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
629 bool
630 operator< (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
632 return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
635 template <class _T1, class _T2, class _U1, class _U2>
636 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
637 bool
638 operator> (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
640 return __y < __x;
643 template <class _T1, class _T2, class _U1, class _U2>
644 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
645 bool
646 operator>=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
648 return !(__x < __y);
651 template <class _T1, class _T2, class _U1, class _U2>
652 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
653 bool
654 operator<=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y)
656 return !(__y < __x);
659 #endif // _LIBCPP_STD_VER >= 20
661 #if _LIBCPP_STD_VER >= 23
662 template <class _T1, class _T2, class _U1, class _U2, template<class> class _TQual, template<class> class _UQual>
663 requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
664 common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
665 struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual> {
666 using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
667 common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
670 template <class _T1, class _T2, class _U1, class _U2>
671 requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
672 struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> {
673 using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>;
675 #endif // _LIBCPP_STD_VER >= 23
677 template <class _T1, class _T2, __enable_if_t<__is_swappable<_T1>::value && __is_swappable<_T2>::value, int> = 0>
678 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
679 void
680 swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
681 _NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&
682 __is_nothrow_swappable<_T2>::value))
684 __x.swap(__y);
687 #if _LIBCPP_STD_VER >= 23
688 template <class _T1, class _T2>
689 requires (__is_swappable<const _T1>::value &&
690 __is_swappable<const _T2>::value)
691 _LIBCPP_HIDE_FROM_ABI constexpr
692 void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
693 noexcept(noexcept(__x.swap(__y)))
695 __x.swap(__y);
697 #endif
699 template <class _T1, class _T2>
700 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
701 pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
702 make_pair(_T1&& __t1, _T2&& __t2)
704 return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
705 (std::forward<_T1>(__t1), std::forward<_T2>(__t2));
708 template <class _T1, class _T2>
709 struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
710 : public integral_constant<size_t, 2> {};
712 template <size_t _Ip, class _T1, class _T2>
713 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
715 static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
718 template <class _T1, class _T2>
719 struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
721 using type _LIBCPP_NODEBUG = _T1;
724 template <class _T1, class _T2>
725 struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> >
727 using type _LIBCPP_NODEBUG = _T2;
730 template <size_t _Ip> struct __get_pair;
732 template <>
733 struct __get_pair<0>
735 template <class _T1, class _T2>
736 static
737 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
738 _T1&
739 get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
741 template <class _T1, class _T2>
742 static
743 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
744 const _T1&
745 get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
747 template <class _T1, class _T2>
748 static
749 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
750 _T1&&
751 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T1>(__p.first);}
753 template <class _T1, class _T2>
754 static
755 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
756 const _T1&&
757 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T1>(__p.first);}
760 template <>
761 struct __get_pair<1>
763 template <class _T1, class _T2>
764 static
765 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
766 _T2&
767 get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
769 template <class _T1, class _T2>
770 static
771 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
772 const _T2&
773 get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
775 template <class _T1, class _T2>
776 static
777 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
778 _T2&&
779 get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T2>(__p.second);}
781 template <class _T1, class _T2>
782 static
783 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
784 const _T2&&
785 get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T2>(__p.second);}
788 template <size_t _Ip, class _T1, class _T2>
789 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
790 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
791 get(pair<_T1, _T2>& __p) _NOEXCEPT
793 return __get_pair<_Ip>::get(__p);
796 template <size_t _Ip, class _T1, class _T2>
797 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
798 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
799 get(const pair<_T1, _T2>& __p) _NOEXCEPT
801 return __get_pair<_Ip>::get(__p);
804 template <size_t _Ip, class _T1, class _T2>
805 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
806 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
807 get(pair<_T1, _T2>&& __p) _NOEXCEPT
809 return __get_pair<_Ip>::get(std::move(__p));
812 template <size_t _Ip, class _T1, class _T2>
813 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
814 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
815 get(const pair<_T1, _T2>&& __p) _NOEXCEPT
817 return __get_pair<_Ip>::get(std::move(__p));
820 #if _LIBCPP_STD_VER >= 14
821 template <class _T1, class _T2>
822 inline _LIBCPP_HIDE_FROM_ABI
823 constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT
825 return __get_pair<0>::get(__p);
828 template <class _T1, class _T2>
829 inline _LIBCPP_HIDE_FROM_ABI
830 constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT
832 return __get_pair<0>::get(__p);
835 template <class _T1, class _T2>
836 inline _LIBCPP_HIDE_FROM_ABI
837 constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT
839 return __get_pair<0>::get(std::move(__p));
842 template <class _T1, class _T2>
843 inline _LIBCPP_HIDE_FROM_ABI
844 constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT
846 return __get_pair<0>::get(std::move(__p));
849 template <class _T1, class _T2>
850 inline _LIBCPP_HIDE_FROM_ABI
851 constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT
853 return __get_pair<1>::get(__p);
856 template <class _T1, class _T2>
857 inline _LIBCPP_HIDE_FROM_ABI
858 constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT
860 return __get_pair<1>::get(__p);
863 template <class _T1, class _T2>
864 inline _LIBCPP_HIDE_FROM_ABI
865 constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT
867 return __get_pair<1>::get(std::move(__p));
870 template <class _T1, class _T2>
871 inline _LIBCPP_HIDE_FROM_ABI
872 constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT
874 return __get_pair<1>::get(std::move(__p));
877 #endif // _LIBCPP_STD_VER >= 14
879 _LIBCPP_END_NAMESPACE_STD
881 _LIBCPP_POP_MACROS
883 #endif // _LIBCPP___UTILITY_PAIR_H