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