Warning: This file is not a C or C++ file. It does not have highlighting.

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

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of libcxx/include/__utility/pair.h