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