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