//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// // Modifications Copyright (c) 2024-2025 Advanced Micro Devices, Inc. // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #ifndef _LIBCUDACXX___UTILITY_PAIR_H #define _LIBCUDACXX___UTILITY_PAIR_H #include #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) # pragma GCC system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG) # pragma clang system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC) # pragma system_header #endif // no system header #if _LIBCUDACXX_HAS_SPACESHIP_OPERATOR() # include # include #endif // _LIBCUDACXX_HAS_SPACESHIP_OPERATOR() #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Provide compatibility between `std::pair` and `cuda::std::pair` #if !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) # include #endif // !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) _LIBCUDACXX_BEGIN_NAMESPACE_STD struct __invalid_pair_constraints { static constexpr bool __implicit_constructible = false; static constexpr bool __explicit_constructible = false; static constexpr bool __enable_assign = false; }; template struct __pair_constraints { static constexpr bool __implicit_default_constructible = __is_implicitly_default_constructible<_T1>::value && __is_implicitly_default_constructible<_T2>::value; static constexpr bool __explicit_default_constructible = !__implicit_default_constructible && _CCCL_TRAIT(is_default_constructible, _T1) && _CCCL_TRAIT(is_default_constructible, _T2); static constexpr bool __explicit_constructible_from_elements = _CCCL_TRAIT(is_copy_constructible, _T1) && _CCCL_TRAIT(is_copy_constructible, _T2) && (!_CCCL_TRAIT(is_convertible, __make_const_lvalue_ref<_T1>, _T1) || !_CCCL_TRAIT(is_convertible, __make_const_lvalue_ref<_T2>, _T2)); static constexpr bool __implicit_constructible_from_elements = _CCCL_TRAIT(is_copy_constructible, _T1) && _CCCL_TRAIT(is_copy_constructible, _T2) && _CCCL_TRAIT(is_convertible, __make_const_lvalue_ref<_T1>, _T1) && _CCCL_TRAIT(is_convertible, __make_const_lvalue_ref<_T2>, _T2); template struct __constructible { static constexpr bool __explicit_constructible = _CCCL_TRAIT(is_constructible, _T1, _U1) && _CCCL_TRAIT(is_constructible, _T2, _U2) && (!_CCCL_TRAIT(is_convertible, _U1, _T1) || !_CCCL_TRAIT(is_convertible, _U2, _T2)); static constexpr bool __implicit_constructible = _CCCL_TRAIT(is_constructible, _T1, _U1) && _CCCL_TRAIT(is_constructible, _T2, _U2) && _CCCL_TRAIT(is_convertible, _U1, _T1) && _CCCL_TRAIT(is_convertible, _U2, _T2); }; template struct __assignable { static constexpr bool __enable_assign = _CCCL_TRAIT(is_assignable, _T1&, _U1) && _CCCL_TRAIT(is_assignable, _T2&, _U2); }; }; // base class to ensure `is_trivially_copyable` when possible template || __must_synthesize_assignment_v<_T2>> struct __pair_base { _T1 first; _T2 second; _CCCL_EXEC_CHECK_DISABLE template , enable_if_t<_Constraints::__explicit_default_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI explicit constexpr __pair_base() noexcept( _CCCL_TRAIT(is_nothrow_default_constructible, _T1) && _CCCL_TRAIT(is_nothrow_default_constructible, _T2)) : first() , second() {} _CCCL_EXEC_CHECK_DISABLE template , enable_if_t<_Constraints::__implicit_default_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI constexpr __pair_base() noexcept( _CCCL_TRAIT(is_nothrow_default_constructible, _T1) && _CCCL_TRAIT(is_nothrow_default_constructible, _T2)) : first() , second() {} _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr __pair_base(_U1&& __t1, _U2&& __t2) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, _U1) && _CCCL_TRAIT(is_nothrow_constructible, _T2, _U2)) : first(_CUDA_VSTD::forward<_U1>(__t1)) , second(_CUDA_VSTD::forward<_U2>(__t2)) {} protected: template _LIBCUDACXX_HIDE_FROM_ABI _CCCL_CONSTEXPR_CXX20 __pair_base( piecewise_construct_t, tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, __tuple_indices<_I1...>, __tuple_indices<_I2...>); }; template struct __pair_base<_T1, _T2, true> { _T1 first; _T2 second; _CCCL_EXEC_CHECK_DISABLE template , enable_if_t<_Constraints::__explicit_default_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI explicit constexpr __pair_base() noexcept( _CCCL_TRAIT(is_nothrow_default_constructible, _T1) && _CCCL_TRAIT(is_nothrow_default_constructible, _T2)) : first() , second() {} _CCCL_EXEC_CHECK_DISABLE template , enable_if_t<_Constraints::__implicit_default_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI constexpr __pair_base() noexcept( _CCCL_TRAIT(is_nothrow_default_constructible, _T1) && _CCCL_TRAIT(is_nothrow_default_constructible, _T2)) : first() , second() {} _CCCL_EXEC_CHECK_DISABLE _CCCL_HIDE_FROM_ABI constexpr __pair_base(const __pair_base&) = default; _CCCL_EXEC_CHECK_DISABLE _CCCL_HIDE_FROM_ABI constexpr __pair_base(__pair_base&&) = default; // We need to ensure that a reference type, which would inhibit the implicit copy assignment still works _CCCL_EXEC_CHECK_DISABLE _LIBCUDACXX_HIDE_FROM_ABI constexpr __pair_base& operator=( conditional_t<_CCCL_TRAIT(is_copy_assignable, _T1) && _CCCL_TRAIT(is_copy_assignable, _T2), __pair_base, __nat> const& __p) noexcept(_CCCL_TRAIT(is_nothrow_copy_assignable, _T1) && _CCCL_TRAIT(is_nothrow_copy_assignable, _T2)) { first = __p.first; second = __p.second; return *this; } // We need to ensure that a reference type, which would inhibit the implicit move assignment still works _CCCL_EXEC_CHECK_DISABLE _LIBCUDACXX_HIDE_FROM_ABI constexpr __pair_base& operator=( conditional_t<_CCCL_TRAIT(is_move_assignable, _T1) && _CCCL_TRAIT(is_move_assignable, _T2), __pair_base, __nat>&& __p) noexcept(_CCCL_TRAIT(is_nothrow_move_assignable, _T1) && _CCCL_TRAIT(is_nothrow_move_assignable, _T2)) { first = _CUDA_VSTD::forward<_T1>(__p.first); second = _CUDA_VSTD::forward<_T2>(__p.second); return *this; } _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr __pair_base(_U1&& __t1, _U2&& __t2) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, _U1) && _CCCL_TRAIT(is_nothrow_constructible, _T2, _U2)) : first(_CUDA_VSTD::forward<_U1>(__t1)) , second(_CUDA_VSTD::forward<_U2>(__t2)) {} protected: template _LIBCUDACXX_HIDE_FROM_ABI _CCCL_CONSTEXPR_CXX20 __pair_base( piecewise_construct_t, tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, __tuple_indices<_I1...>, __tuple_indices<_I2...>); }; template struct _CCCL_TYPE_VISIBILITY_DEFAULT pair : public __pair_base<_T1, _T2> { using __base = __pair_base<_T1, _T2>; using first_type = _T1; using second_type = _T2; template , enable_if_t<_Constraints::__explicit_default_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI explicit constexpr pair() noexcept( _CCCL_TRAIT(is_nothrow_default_constructible, _T1) && _CCCL_TRAIT(is_nothrow_default_constructible, _T2)) : __base() {} template , enable_if_t<_Constraints::__implicit_default_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI constexpr pair() noexcept( _CCCL_TRAIT(is_nothrow_default_constructible, _T1) && _CCCL_TRAIT(is_nothrow_default_constructible, _T2)) : __base() {} // element wise constructors template , enable_if_t<_Constraints::__explicit_constructible_from_elements, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI explicit constexpr pair(const _T1& __t1, const _T2& __t2) noexcept( _CCCL_TRAIT(is_nothrow_copy_constructible, _T1) && _CCCL_TRAIT(is_nothrow_copy_constructible, _T2)) : __base(__t1, __t2) {} template , enable_if_t<_Constraints::__implicit_constructible_from_elements, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI constexpr pair(const _T1& __t1, const _T2& __t2) noexcept( _CCCL_TRAIT(is_nothrow_copy_constructible, _T1) && _CCCL_TRAIT(is_nothrow_copy_constructible, _T2)) : __base(__t1, __t2) {} template using __pair_constructible = typename __pair_constraints<_T1, _T2>::template __constructible<_U1, _U2>; template , enable_if_t<_Constraints::__explicit_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI explicit constexpr pair(_U1&& __u1, _U2&& __u2) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, _U1) && _CCCL_TRAIT(is_nothrow_constructible, _T2, _U2)) : __base(_CUDA_VSTD::forward<_U1>(__u1), _CUDA_VSTD::forward<_U2>(__u2)) {} template , enable_if_t<_Constraints::__implicit_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI constexpr pair(_U1&& __u1, _U2&& __u2) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, _U1) && _CCCL_TRAIT(is_nothrow_constructible, _T2, _U2)) : __base(_CUDA_VSTD::forward<_U1>(__u1), _CUDA_VSTD::forward<_U2>(__u2)) {} template _LIBCUDACXX_HIDE_FROM_ABI _CCCL_CONSTEXPR_CXX20 pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) noexcept( (is_nothrow_constructible<_T1, _Args1...>::value && is_nothrow_constructible<_T2, _Args2...>::value)) : __base(__pc, __first_args, __second_args, __make_tuple_indices_t(), __make_tuple_indices_t()) {} // copy and move constructors _CCCL_HIDE_FROM_ABI pair(pair const&) = default; _CCCL_HIDE_FROM_ABI pair(pair&&) = default; template , enable_if_t<_Constraints::__explicit_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI explicit constexpr pair(const pair<_U1, _U2>& __p) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, const _U1&) && _CCCL_TRAIT(is_nothrow_constructible, _T2, const _U2&)) : __base(__p.first, __p.second) {} template , enable_if_t<_Constraints::__implicit_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI constexpr pair(const pair<_U1, _U2>& __p) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, const _U1&) && _CCCL_TRAIT(is_nothrow_constructible, _T2, const _U2&)) : __base(__p.first, __p.second) {} // move constructors template , enable_if_t<_Constraints::__explicit_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI explicit constexpr pair(pair<_U1, _U2>&& __p) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, _U1) && _CCCL_TRAIT(is_nothrow_constructible, _T2, _U2)) : __base(_CUDA_VSTD::forward<_U1>(__p.first), _CUDA_VSTD::forward<_U2>(__p.second)) {} template , enable_if_t<_Constraints::__implicit_constructible, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI constexpr pair(pair<_U1, _U2>&& __p) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, _U1) && _CCCL_TRAIT(is_nothrow_constructible, _T2, _U2)) : __base(_CUDA_VSTD::forward<_U1>(__p.first), _CUDA_VSTD::forward<_U2>(__p.second)) {} // std compatibility #if !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) template , enable_if_t<_Constraints::__explicit_constructible, int> = 0> _CCCL_HOST _LIBCUDACXX_HIDE_FROM_ABI explicit constexpr pair(const ::std::pair<_U1, _U2>& __p) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, const _U1&) && _CCCL_TRAIT(is_nothrow_constructible, _T2, const _U2&)) : __base(__p.first, __p.second) {} template , enable_if_t<_Constraints::__implicit_constructible, int> = 0> _CCCL_HOST _LIBCUDACXX_HIDE_FROM_ABI constexpr pair(const ::std::pair<_U1, _U2>& __p) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, const _U1&) && _CCCL_TRAIT(is_nothrow_constructible, _T2, const _U2&)) : __base(__p.first, __p.second) {} template , enable_if_t<_Constraints::__explicit_constructible, int> = 0> _CCCL_HOST _LIBCUDACXX_HIDE_FROM_ABI explicit constexpr pair(::std::pair<_U1, _U2>&& __p) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, _U1) && _CCCL_TRAIT(is_nothrow_constructible, _T2, _U2)) : __base(_CUDA_VSTD::forward<_U1>(__p.first), _CUDA_VSTD::forward<_U2>(__p.second)) {} template , enable_if_t<_Constraints::__implicit_constructible, int> = 0> _CCCL_HOST _LIBCUDACXX_HIDE_FROM_ABI constexpr pair(::std::pair<_U1, _U2>&& __p) noexcept( _CCCL_TRAIT(is_nothrow_constructible, _T1, _U1) && _CCCL_TRAIT(is_nothrow_constructible, _T2, _U2)) : __base(_CUDA_VSTD::forward<_U1>(__p.first), _CUDA_VSTD::forward<_U2>(__p.second)) {} #endif // !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) // assignments _CCCL_HIDE_FROM_ABI pair& operator=(const pair&) = default; _CCCL_HIDE_FROM_ABI pair& operator=(pair&&) = default; template ::template __assignable, enable_if_t<_Constraints::__enable_assign, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI constexpr pair& operator=(const pair<_U1, _U2>& __p) noexcept( _CCCL_TRAIT(is_nothrow_assignable, _T1, const _U1&) && _CCCL_TRAIT(is_nothrow_assignable, _T2, const _U2&)) { this->first = __p.first; this->second = __p.second; return *this; } template ::template __assignable<_U1, _U2>, enable_if_t<_Constraints::__enable_assign, int> = 0> _LIBCUDACXX_HIDE_FROM_ABI constexpr pair& operator=(pair<_U1, _U2>&& __p) noexcept( _CCCL_TRAIT(is_nothrow_assignable, _T1, _U1) && _CCCL_TRAIT(is_nothrow_assignable, _T2, _U2)) { this->first = _CUDA_VSTD::forward<_U1>(__p.first); this->second = _CUDA_VSTD::forward<_U2>(__p.second); return *this; } // std assignments #if !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) template ::value && is_copy_assignable<_T2>::value, int> = 0> _CCCL_HOST constexpr pair& operator=(::std::pair<_T1, _T2> const& __p) noexcept( _CCCL_TRAIT(is_nothrow_copy_assignable, _T1) && _CCCL_TRAIT(is_nothrow_copy_assignable, _T2)) { this->first = __p.first; this->second = __p.second; return *this; } template ::value && is_move_assignable<_T2>::value, int> = 0> _CCCL_HOST constexpr pair& operator=(::std::pair<_T1, _T2>&& __p) noexcept( _CCCL_TRAIT(is_nothrow_copy_assignable, _T1) && _CCCL_TRAIT(is_nothrow_copy_assignable, _T2)) { this->first = _CUDA_VSTD::forward<_T1>(__p.first); this->second = _CUDA_VSTD::forward<_T2>(__p.second); return *this; } #endif // !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) #if _CCCL_STD_VER >= 2023 _LIBCUDACXX_HIDE_FROM_ABI constexpr const pair& operator=(pair const& __p) const noexcept(_CCCL_TRAIT(is_nothrow_copy_assignable, const _T1) && _CCCL_TRAIT(is_nothrow_copy_assignable, const _T2)) requires(is_copy_assignable_v && is_copy_assignable_v) { this->first = __p.first; this->second = __p.second; return *this; } # if !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) _LIBCUDACXX_HIDE_FROM_ABI _CCCL_HOST constexpr const pair& operator=(::std::pair<_T1, _T2> const& __p) const noexcept(_CCCL_TRAIT(is_nothrow_copy_assignable, const _T1) && _CCCL_TRAIT(is_nothrow_copy_assignable, const _T2)) requires(is_copy_assignable_v && is_copy_assignable_v) { this->first = __p.first; this->second = __p.second; return *this; } # endif // !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) _LIBCUDACXX_HIDE_FROM_ABI constexpr const pair& operator=(pair&& __p) const noexcept(_CCCL_TRAIT(is_nothrow_assignable, const _T1&, _T1) && _CCCL_TRAIT(is_nothrow_assignable, const _T2&, _T2)) requires(is_assignable_v && is_assignable_v) { this->first = _CUDA_VSTD::forward<_T1>(__p.first); this->second = _CUDA_VSTD::forward<_T2>(__p.second); return *this; } # if !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) _LIBCUDACXX_HIDE_FROM_ABI _CCCL_HOST constexpr const pair& operator=(::std::pair<_T1, _T2>&& __p) const noexcept(_CCCL_TRAIT(is_nothrow_assignable, const _T1&, _T1) && _CCCL_TRAIT(is_nothrow_assignable, const _T2&, _T2)) requires(is_assignable_v && is_assignable_v) { this->first = _CUDA_VSTD::forward<_T1>(__p.first); this->second = _CUDA_VSTD::forward<_T2>(__p.second); return *this; } # endif // !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) template _LIBCUDACXX_HIDE_FROM_ABI constexpr const pair& operator=(const pair<_U1, _U2>& __p) const requires(is_assignable_v && is_assignable_v) { this->first = __p.first; this->second = __p.second; return *this; } # if !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) template _LIBCUDACXX_HIDE_FROM_ABI _CCCL_HOST constexpr const pair& operator=(const ::std::pair<_U1, _U2>& __p) const requires(is_assignable_v && is_assignable_v) { this->first = __p.first; this->second = __p.second; return *this; } # endif // !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) template _LIBCUDACXX_HIDE_FROM_ABI constexpr const pair& operator=(pair<_U1, _U2>&& __p) const requires(is_assignable_v && is_assignable_v) { this->first = _CUDA_VSTD::forward<_U1>(__p.first); this->second = _CUDA_VSTD::forward<_U2>(__p.second); return *this; } # if !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) template _LIBCUDACXX_HIDE_FROM_ABI _CCCL_HOST constexpr const pair& operator=(::std::pair<_U1, _U2>&& __p) const requires(is_assignable_v && is_assignable_v) { this->first = _CUDA_VSTD::forward<_U1>(__p.first); this->second = _CUDA_VSTD::forward<_U2>(__p.second); return *this; } # endif // !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) #endif // _CCCL_STD_VER >= 2023 _LIBCUDACXX_HIDE_FROM_ABI _CCCL_CONSTEXPR_CXX20 void swap(pair& __p) noexcept(__is_nothrow_swappable<_T1>::value && __is_nothrow_swappable<_T2>::value) { using _CUDA_VSTD::swap; swap(this->first, __p.first); swap(this->second, __p.second); } #if _CCCL_STD_VER >= 2023 _LIBCUDACXX_HIDE_FROM_ABI constexpr void swap(const pair& __p) const noexcept(__is_nothrow_swappable::value && __is_nothrow_swappable::value) { using _CUDA_VSTD::swap; swap(this->first, __p.first); swap(this->second, __p.second); } #endif // _CCCL_STD_VER >= 2023 #if !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) _CCCL_HOST constexpr operator ::std::pair<_T1, _T2>() const { return {this->first, this->second}; } #endif // !_CCCL_COMPILER(NVRTC) && !defined(_CCCL_COMPILER_HIPRTC) }; #if !defined(_CCCL_NO_DEDUCTION_GUIDES) template _CCCL_HOST_DEVICE pair(_T1, _T2) -> pair<_T1, _T2>; #endif // !_CCCL_NO_DEDUCTION_GUIDES // [pairs.spec], specialized algorithms _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr bool operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return __x.first == __y.first && __x.second == __y.second; } #if _LIBCUDACXX_HAS_SPACESHIP_OPERATOR() _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr common_comparison_category_t<__synth_three_way_result<_T1>, __synth_three_way_result<_T2>> operator<=>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { if (auto __c = _CUDA_VSTD::__synth_three_way(__x.first, __y.first); __c != 0) { return __c; } return _CUDA_VSTD::__synth_three_way(__x.second, __y.second); } #else // ^^^ _LIBCUDACXX_HAS_SPACESHIP_OPERATOR() ^^^ / vvv !_LIBCUDACXX_HAS_SPACESHIP_OPERATOR() vvv _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr bool operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return !(__x == __y); } _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr bool operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second); } _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr bool operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return __y < __x; } _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return !(__x < __y); } _CCCL_EXEC_CHECK_DISABLE template _LIBCUDACXX_HIDE_FROM_ABI constexpr bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { return !(__y < __x); } #endif // !_LIBCUDACXX_HAS_SPACESHIP_OPERATOR() #if _CCCL_STD_VER >= 2023 template class _TQual, template class _UQual> requires requires { typename pair, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>; } struct basic_common_reference, pair<_U1, _U2>, _TQual, _UQual> { using type = pair, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }; template requires requires { typename pair, common_type_t<_T2, _U2>>; } struct common_type, pair<_U1, _U2>> { using type = pair, common_type_t<_T2, _U2>>; }; #endif // _CCCL_STD_VER >= 2023 template _LIBCUDACXX_HIDE_FROM_ABI _CCCL_CONSTEXPR_CXX20 enable_if_t<__is_swappable<_T1>::value && __is_swappable<_T2>::value, void> swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) noexcept((__is_nothrow_swappable<_T1>::value && __is_nothrow_swappable<_T2>::value)) { __x.swap(__y); } #if _CCCL_STD_VER >= 2023 template requires(__is_swappable::value && __is_swappable::value) _LIBCUDACXX_HIDE_FROM_ABI constexpr void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } #endif // _CCCL_STD_VER >= 2023 template _LIBCUDACXX_HIDE_FROM_ABI constexpr pair::type, typename __unwrap_ref_decay<_T2>::type> make_pair(_T1&& __t1, _T2&& __t2) { return pair::type, typename __unwrap_ref_decay<_T2>::type>( _CUDA_VSTD::forward<_T1>(__t1), _CUDA_VSTD::forward<_T2>(__t2)); } template struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_size> : public integral_constant {}; template struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_element<_Ip, pair<_T1, _T2>> { static_assert(_Ip < 2, "Index out of bounds in std::tuple_element>"); }; template struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_element<0, pair<_T1, _T2>> { using type _CCCL_NODEBUG_ALIAS = _T1; }; template struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_element<1, pair<_T1, _T2>> { using type _CCCL_NODEBUG_ALIAS = _T2; }; template struct __get_pair; template <> struct __get_pair<0> { template static _LIBCUDACXX_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) noexcept { return __p.first; } template static _LIBCUDACXX_HIDE_FROM_ABI constexpr const _T1& get(const pair<_T1, _T2>& __p) noexcept { return __p.first; } template static _LIBCUDACXX_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) noexcept { return _CUDA_VSTD::forward<_T1>(__p.first); } template static _LIBCUDACXX_HIDE_FROM_ABI constexpr const _T1&& get(const pair<_T1, _T2>&& __p) noexcept { return _CUDA_VSTD::forward(__p.first); } }; template <> struct __get_pair<1> { template static _LIBCUDACXX_HIDE_FROM_ABI constexpr _T2& get(pair<_T1, _T2>& __p) noexcept { return __p.second; } template static _LIBCUDACXX_HIDE_FROM_ABI constexpr const _T2& get(const pair<_T1, _T2>& __p) noexcept { return __p.second; } template static _LIBCUDACXX_HIDE_FROM_ABI constexpr _T2&& get(pair<_T1, _T2>&& __p) noexcept { return _CUDA_VSTD::forward<_T2>(__p.second); } template static _LIBCUDACXX_HIDE_FROM_ABI constexpr const _T2&& get(const pair<_T1, _T2>&& __p) noexcept { return _CUDA_VSTD::forward(__p.second); } }; template _LIBCUDACXX_HIDE_FROM_ABI constexpr __tuple_element_t<_Ip, pair<_T1, _T2>>& get(pair<_T1, _T2>& __p) noexcept { return __get_pair<_Ip>::get(__p); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr const __tuple_element_t<_Ip, pair<_T1, _T2>>& get(const pair<_T1, _T2>& __p) noexcept { return __get_pair<_Ip>::get(__p); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr __tuple_element_t<_Ip, pair<_T1, _T2>>&& get(pair<_T1, _T2>&& __p) noexcept { return __get_pair<_Ip>::get(_CUDA_VSTD::move(__p)); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr const __tuple_element_t<_Ip, pair<_T1, _T2>>&& get(const pair<_T1, _T2>&& __p) noexcept { return __get_pair<_Ip>::get(_CUDA_VSTD::move(__p)); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr _T1& get(pair<_T1, _T2>& __p) noexcept { return __get_pair<0>::get(__p); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T1, _T2> const& __p) noexcept { return __get_pair<0>::get(__p); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr _T1&& get(pair<_T1, _T2>&& __p) noexcept { return __get_pair<0>::get(_CUDA_VSTD::move(__p)); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) noexcept { return __get_pair<0>::get(_CUDA_VSTD::move(__p)); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr _T1& get(pair<_T2, _T1>& __p) noexcept { return __get_pair<1>::get(__p); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr _T1 const& get(pair<_T2, _T1> const& __p) noexcept { return __get_pair<1>::get(__p); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr _T1&& get(pair<_T2, _T1>&& __p) noexcept { return __get_pair<1>::get(_CUDA_VSTD::move(__p)); } template _LIBCUDACXX_HIDE_FROM_ABI constexpr _T1 const&& get(pair<_T2, _T1> const&& __p) noexcept { return __get_pair<1>::get(_CUDA_VSTD::move(__p)); } _LIBCUDACXX_END_NAMESPACE_STD #endif // _LIBCUDACXX___UTILITY_PAIR_H