1 //===----------------------------------------------------------------------===//
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
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>
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>
55 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
56 # pragma GCC system_header
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
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
{};
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
>
86 using first_type
= _T1
;
87 using second_type
= _T2
;
92 _LIBCPP_HIDE_FROM_ABI
pair(pair
const&) = default;
93 _LIBCPP_HIDE_FROM_ABI
pair(pair
&&) = default;
95 #ifdef _LIBCPP_CXX03_LANG
97 pair() : first(), second() {}
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
) {
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
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
) {
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
<>();
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
) {}
197 #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
198 class _U1
= _T1
, class _U2
= _T2
,
200 class _U1
, class _U2
,
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
)) {}
211 #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951
212 class _U1
= _T1
, class _U2
= _T2
,
214 class _U1
, class _U2
,
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
&>()
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
) {}
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
&&>()
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
)) {}
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
>;
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
))) {}
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
)
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
,
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
);
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
334 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
335 pair
& operator=(pair
<_U1
, _U2
> const& __p
) {
341 template <class _U1
, class _U2
, __enable_if_t
<
342 is_assignable
<first_type
&, _U1
>::value
&&
343 is_assignable
<second_type
&, _U2
>::value
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
);
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
>) {
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
);
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
&>) {
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
);
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
));
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
));
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
422 template<class _U1
, class _U2
, __enable_if_t
<
423 is_convertible
<_U1
const&, _T1
>::value
&&
424 is_convertible
<_U2
const&, _T2
>::value
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
)
437 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
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
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
)
458 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
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
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
);
476 template<class _U1
, class _U2
, __enable_if_t
<
477 is_assignable
<_T1
&, _U1
&&>::value
&&
478 is_assignable
<_T2
&, _U2
&&>::value
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
));
488 template<class _Up
, __enable_if_t
<
489 is_convertible
<_Up
const&, _T1
>::value
&&
490 is_convertible
<_Up
const&, _T2
>::value
492 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
493 pair(array
<_Up
, 2> const& __p
)
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
)
503 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
505 pair(array
<_Up
, 2> const& __p
)
509 template<class _Up
, __enable_if_t
<
510 is_convertible
<_Up
, _T1
>::value
&&
511 is_convertible
<_Up
, _T2
>::value
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
)
524 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
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
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
);
542 template<class _Up
, __enable_if_t
<
543 is_assignable
<_T1
&, _Up
>::value
&&
544 is_assignable
<_T2
&, _Up
>::value
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
));
552 #endif // _LIBCPP_STD_VER < 23
553 #endif // _LIBCPP_CXX03_LANG
555 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
557 swap(pair
& __p
) _NOEXCEPT_(__is_nothrow_swappable
<first_type
>::value
&&
558 __is_nothrow_swappable
<second_type
>::value
)
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
)
572 swap(first
, __p
.first
);
573 swap(second
, __p
.second
);
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
...>);
587 #if _LIBCPP_STD_VER >= 17
588 template<class _T1
, class _T2
>
589 pair(_T1
, _T2
) -> pair
<_T1
, _T2
>;
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
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) {
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
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
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
638 operator> (const pair
<_T1
,_T2
>& __x
, const pair
<_U1
,_U2
>& __y
)
643 template <class _T1
, class _T2
, class _U1
, class _U2
>
644 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
646 operator>=(const pair
<_T1
,_T2
>& __x
, const pair
<_U1
,_U2
>& __y
)
651 template <class _T1
, class _T2
, class _U1
, class _U2
>
652 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
654 operator<=(const pair
<_T1
,_T2
>& __x
, const pair
<_U1
,_U2
>& __y
)
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
680 swap(pair
<_T1
, _T2
>& __x
, pair
<_T1
, _T2
>& __y
)
681 _NOEXCEPT_((__is_nothrow_swappable
<_T1
>::value
&&
682 __is_nothrow_swappable
<_T2
>::value
))
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
)))
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
;
735 template <class _T1
, class _T2
>
737 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
739 get(pair
<_T1
, _T2
>& __p
) _NOEXCEPT
{return __p
.first
;}
741 template <class _T1
, class _T2
>
743 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
745 get(const pair
<_T1
, _T2
>& __p
) _NOEXCEPT
{return __p
.first
;}
747 template <class _T1
, class _T2
>
749 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
751 get(pair
<_T1
, _T2
>&& __p
) _NOEXCEPT
{return std::forward
<_T1
>(__p
.first
);}
753 template <class _T1
, class _T2
>
755 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
757 get(const pair
<_T1
, _T2
>&& __p
) _NOEXCEPT
{return std::forward
<const _T1
>(__p
.first
);}
763 template <class _T1
, class _T2
>
765 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
767 get(pair
<_T1
, _T2
>& __p
) _NOEXCEPT
{return __p
.second
;}
769 template <class _T1
, class _T2
>
771 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
773 get(const pair
<_T1
, _T2
>& __p
) _NOEXCEPT
{return __p
.second
;}
775 template <class _T1
, class _T2
>
777 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
779 get(pair
<_T1
, _T2
>&& __p
) _NOEXCEPT
{return std::forward
<_T2
>(__p
.second
);}
781 template <class _T1
, class _T2
>
783 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
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
883 #endif // _LIBCPP___UTILITY_PAIR_H