Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libcxx/include/__utility/pair.h
35236 views
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
57
template <class, class>
58
struct __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
64
template <class _T1, class _T2>
65
struct _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
468
private:
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
483
template <class _T1, class _T2>
484
pair(_T1, _T2) -> pair<_T1, _T2>;
485
#endif
486
487
// [pairs.spec], specialized algorithms
488
489
template <class _T1, class _T2, class _U1, class _U2>
490
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
491
operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
492
return __x.first == __y.first && __x.second == __y.second;
493
}
494
495
#if _LIBCPP_STD_VER >= 20
496
497
template <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> >
500
operator<=>(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
509
template <class _T1, class _T2, class _U1, class _U2>
510
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
511
operator!=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
512
return !(__x == __y);
513
}
514
515
template <class _T1, class _T2, class _U1, class _U2>
516
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
517
operator<(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
521
template <class _T1, class _T2, class _U1, class _U2>
522
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
523
operator>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
524
return __y < __x;
525
}
526
527
template <class _T1, class _T2, class _U1, class _U2>
528
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
529
operator>=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
530
return !(__x < __y);
531
}
532
533
template <class _T1, class _T2, class _U1, class _U2>
534
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
535
operator<=(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
542
template <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
}
546
struct 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
550
template <class _T1, class _T2, class _U1, class _U2>
551
requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
552
struct 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
557
template <class _T1, class _T2, __enable_if_t<__is_swappable_v<_T1> && __is_swappable_v<_T2>, int> = 0>
558
inline _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
564
template <class _T1, class _T2>
565
requires(__is_swappable_v<const _T1> && __is_swappable_v<const _T2>)
566
_LIBCPP_HIDE_FROM_ABI constexpr void
567
swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x.swap(__y))) {
568
__x.swap(__y);
569
}
570
#endif
571
572
template <class _T1, class _T2>
573
inline _LIBCPP_HIDE_FROM_ABI
574
_LIBCPP_CONSTEXPR_SINCE_CXX14 pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
575
make_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
580
template <class _T1, class _T2>
581
struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > : public integral_constant<size_t, 2> {};
582
583
template <size_t _Ip, class _T1, class _T2>
584
struct _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
588
template <class _T1, class _T2>
589
struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > {
590
using type _LIBCPP_NODEBUG = _T1;
591
};
592
593
template <class _T1, class _T2>
594
struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > {
595
using type _LIBCPP_NODEBUG = _T2;
596
};
597
598
template <size_t _Ip>
599
struct __get_pair;
600
601
template <>
602
struct __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
624
template <>
625
struct __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
647
template <size_t _Ip, class _T1, class _T2>
648
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
649
get(pair<_T1, _T2>& __p) _NOEXCEPT {
650
return __get_pair<_Ip>::get(__p);
651
}
652
653
template <size_t _Ip, class _T1, class _T2>
654
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
655
get(const pair<_T1, _T2>& __p) _NOEXCEPT {
656
return __get_pair<_Ip>::get(__p);
657
}
658
659
template <size_t _Ip, class _T1, class _T2>
660
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
661
get(pair<_T1, _T2>&& __p) _NOEXCEPT {
662
return __get_pair<_Ip>::get(std::move(__p));
663
}
664
665
template <size_t _Ip, class _T1, class _T2>
666
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
667
get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
668
return __get_pair<_Ip>::get(std::move(__p));
669
}
670
671
#if _LIBCPP_STD_VER >= 14
672
template <class _T1, class _T2>
673
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
674
return __get_pair<0>::get(__p);
675
}
676
677
template <class _T1, class _T2>
678
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) _NOEXCEPT {
679
return __get_pair<0>::get(__p);
680
}
681
682
template <class _T1, class _T2>
683
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
684
return __get_pair<0>::get(std::move(__p));
685
}
686
687
template <class _T1, class _T2>
688
inline _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
692
template <class _T1, class _T2>
693
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(pair<_T2, _T1>& __p) _NOEXCEPT {
694
return __get_pair<1>::get(__p);
695
}
696
697
template <class _T1, class _T2>
698
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T2, _T1> const& __p) _NOEXCEPT {
699
return __get_pair<1>::get(__p);
700
}
701
702
template <class _T1, class _T2>
703
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1&& get(pair<_T2, _T1>&& __p) _NOEXCEPT {
704
return __get_pair<1>::get(std::move(__p));
705
}
706
707
template <class _T1, class _T2>
708
inline _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
720