From a4a32892ba8af11e30e3818b151c8604896ad714 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Wed, 17 Jan 2024 19:57:18 -0800 Subject: [PATCH] Ensure that `cuda::std::pair` is potentially trivially copyable (#1249) trivially copyable is a requirement for memcpy. We want to ensure that our pair implementation satisfies that whenever possible. This is especially important for thrust::pair as that is used in rmm extensively. Fixes #1246 Co-authored-by: Georgy Evtushenko --- .../cuda/std/detail/libcxx/include/__config | 10 - .../detail/libcxx/include/__utility/pair.h | 1230 ++++++++--------- .../cuda/std/detail/libcxx/include/tuple | 19 +- .../std/detail/libcxx/include/type_traits | 2 +- .../non_trivial_copy_move_ABI.pass.cpp | 162 --- .../pairs.pair/trivial_copy_move_ABI.pass.cpp | 4 - .../pairs.pair/trivial_copy_move.pass.cpp | 6 - .../optional.object/special_members.pass.cpp | 3 - .../optional.object/triviality.pass.cpp | 3 - .../pairs.pair/trivial_copy_move.pass.cpp | 19 +- libcudacxx/test/support/archetypes.ipp | 21 +- .../system/detail/sequential/partition.h | 5 + .../system/detail/sequential/trivial_copy.h | 7 + 13 files changed, 656 insertions(+), 835 deletions(-) delete mode 100644 libcudacxx/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/__config b/libcudacxx/include/cuda/std/detail/libcxx/include/__config index e26e354237f..24da7330fe0 100644 --- a/libcudacxx/include/cuda/std/detail/libcxx/include/__config +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/__config @@ -184,16 +184,6 @@ extern "C++" { // conflict with the dllexport-emitted copy, so we disable it. # define _LIBCUDACXX_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS # endif -// Feature macros for disabling pre ABI v1 features. All of these options -// are deprecated. -# if defined(__FreeBSD__) -# define _LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR -# endif -#endif - -#ifdef _LIBCUDACXX_TRIVIAL_PAIR_COPY_CTOR -#error "_LIBCUDACXX_TRIVIAL_PAIR_COPY_CTOR" is no longer supported. \ - use _LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR instead #endif #ifndef __has_attribute diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/__utility/pair.h b/libcudacxx/include/cuda/std/detail/libcxx/include/__utility/pair.h index e4d8abd80c7..3127b5e52b5 100644 --- a/libcudacxx/include/cuda/std/detail/libcxx/include/__utility/pair.h +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/__utility/pair.h @@ -11,16 +11,17 @@ #define _LIBCUDACXX___UTILITY_PAIR_H #ifndef __cuda_std__ -#include <__config> +# include <__config> #endif // __cuda_std__ #ifndef _LIBCUDACXX_HAS_NO_SPACESHIP_OPERATOR -#include "../__compare/common_comparison_category.h" -#include "../__compare/synth_three_way.h" +# include "../__compare/common_comparison_category.h" +# include "../__compare/synth_three_way.h" #endif // _LIBCUDACXX_HAS_NO_SPACESHIP_OPERATOR #include "../__functional/unwrap_ref.h" #include "../__fwd/get.h" +#include "../__fwd/pair.h" #include "../__fwd/tuple.h" #include "../__tuple_dir/sfinae_helpers.h" #include "../__tuple_dir/structured_bindings.h" @@ -56,7 +57,7 @@ // Provide compatability between `std::pair` and `cuda::std::pair` #if defined(__cuda_std__) && !defined(__CUDACC_RTC__) -#include +# include #endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) @@ -69,707 +70,696 @@ _LIBCUDACXX_BEGIN_NAMESPACE_STD -#if defined(_LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) -template -struct __non_trivially_copyable_base { - _LIBCUDACXX_INLINE_VISIBILITY constexpr - __non_trivially_copyable_base() noexcept {} - _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 _LIBCUDACXX_INLINE_VISIBILITY - __non_trivially_copyable_base(__non_trivially_copyable_base const&) noexcept {} +struct __invalid_pair_constraints +{ + static constexpr bool __implicit_constructible = false; + static constexpr bool __explicit_constructible = false; + static constexpr bool __enable_assign = false; }; -#endif template -struct _LIBCUDACXX_TEMPLATE_VIS pair -#if defined(_LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) -: private __non_trivially_copyable_base<_T1, _T2> -#endif -{ - typedef _T1 first_type; - typedef _T2 second_type; - - _T1 first; - _T2 second; - - pair(pair const&) = default; - pair(pair&&) = default; - - struct _CheckArgs { - struct __enable_implicit_default : public integral_constant::value - && __is_implicitly_default_constructible<_T2>::value> - {}; - - struct __enable_explicit_default : public integral_constant::value - && is_default_constructible<_T2>::value - && !__enable_implicit_default::value> - {}; - - template - struct __is_pair_constructible : public integral_constant::value - && is_constructible::value> - {}; - - template - struct __is_implicit : public integral_constant::value - && is_convertible<_U2, second_type>::value> - {}; - - template - struct __enable_explicit : public integral_constant::value - && !__is_implicit<_U1, _U2>::value> - {}; - - template - struct __enable_implicit : public integral_constant::value - && __is_implicit<_U1, _U2>::value> - {}; - }; - - template - using _CheckArgsDep _LIBCUDACXX_NODEBUG_TYPE = __conditional_t< - _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>; - - struct _CheckTupleLikeConstructor { - template - struct __enable_implicit : public integral_constant::value> - {}; - template - struct __enable_explicit : public integral_constant::value - && !__tuple_convertible<_Tuple, pair>::value> - {}; - template - struct __enable_assign : public integral_constant::value> - {}; - }; - - template - using _CheckTLC _LIBCUDACXX_NODEBUG_TYPE = __conditional_t< - __tuple_like_with_size<_Tuple, 2>::value - && !is_same<__decay_t<_Tuple>, pair>::value, - _CheckTupleLikeConstructor, - __check_tuple_constructor_fail - >; - - template::__enable_explicit_default::value - >* = nullptr> - explicit _LIBCUDACXX_INLINE_VISIBILITY constexpr - pair() noexcept(is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value) - : first(), second() {} - - template::__enable_implicit_default::value - >* = nullptr> - _LIBCUDACXX_INLINE_VISIBILITY constexpr - pair() noexcept(is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value) - : first(), second() {} - - template ::template __enable_explicit<__make_const_lvalue_ref<_T1>, __make_const_lvalue_ref<_T2>>::value - >* = nullptr> - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - explicit pair(_T1 const& __t1, _T2 const& __t2) - noexcept(is_nothrow_copy_constructible::value && - is_nothrow_copy_constructible::value) - : first(__t1), second(__t2) {} - - template::template __enable_implicit<__make_const_lvalue_ref<_T1>, __make_const_lvalue_ref<_T2>>::value - >* = nullptr> - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - pair(_T1 const& __t1, _T2 const& __t2) - noexcept(is_nothrow_copy_constructible::value && - is_nothrow_copy_constructible::value) - : first(__t1), second(__t2) {} - - template < -#if _CCCL_STD_VER > 2020 // http://wg21.link/P1951 - class _U1 = _T1, class _U2 = _T2, -#else - class _U1, class _U2, -#endif - __enable_if_t<_CheckArgs::template __enable_explicit<_U1, _U2>::value>* = nullptr - > - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - explicit pair(_U1&& __u1, _U2&& __u2) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(_CUDA_VSTD::forward<_U1>(__u1)), second(_CUDA_VSTD::forward<_U2>(__u2)) {} - - template < -#if _CCCL_STD_VER > 2020 // http://wg21.link/P1951 - class _U1 = _T1, class _U2 = _T2, -#else - class _U1, class _U2, -#endif - __enable_if_t<_CheckArgs::template __enable_implicit<_U1, _U2>::value>* = nullptr - > - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - pair(_U1&& __u1, _U2&& __u2) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(_CUDA_VSTD::forward<_U1>(__u1)), second(_CUDA_VSTD::forward<_U2>(__u2)) {} - -#if _CCCL_STD_VER > 2020 - template::value - >* = nullptr> - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr - explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>()) pair(pair<_U1, _U2>& __p) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(__p.first), second(__p.second) {} - -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - template::value - >* = nullptr> - _LIBCUDACXX_HOST _LIBCUDACXX_INLINE_VISIBILITY constexpr - explicit(!_CheckArgs::template __is_implicit<_U1&, _U2&>()) pair(::std::pair<_U1, _U2>& __p) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(__p.first), second(__p.second) {} -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) -#endif // _CCCL_STD_VER > 2020 - - template::value - >* = nullptr> - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - explicit pair(pair<_U1, _U2> const& __p) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(__p.first), second(__p.second) {} - -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - template::value - >* = nullptr> - _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - explicit pair(::std::pair<_U1, _U2> const& __p) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(__p.first), second(__p.second) {} -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) - - template::value - >* = nullptr> - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - pair(pair<_U1, _U2> const& __p) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(__p.first), second(__p.second) {} - -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - template::value - >* = nullptr> - _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - pair(::std::pair<_U1, _U2> const& __p) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(__p.first), second(__p.second) {} -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) - - template::value - >* = nullptr> - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - explicit pair(pair<_U1, _U2>&&__p) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(_CUDA_VSTD::forward<_U1>(__p.first)), second(_CUDA_VSTD::forward<_U2>(__p.second)) {} - -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - template::value - >* = nullptr> - _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - explicit pair(::std::pair<_U1, _U2>&&__p) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(_CUDA_VSTD::forward<_U1>(__p.first)), second(_CUDA_VSTD::forward<_U2>(__p.second)) {} -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) - - template::value - >* = nullptr> - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - pair(pair<_U1, _U2>&& __p) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(_CUDA_VSTD::forward<_U1>(__p.first)), second(_CUDA_VSTD::forward<_U2>(__p.second)) {} - -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - template::value - >* = nullptr> - _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - pair(::std::pair<_U1, _U2>&& __p) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : first(_CUDA_VSTD::forward<_U1>(__p.first)), second(_CUDA_VSTD::forward<_U2>(__p.second)) {} -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) - -#if _CCCL_STD_VER > 2020 - template::value - >* = nullptr> - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr - explicit(!_CheckArgs::template __is_implicit::value) - pair(const pair<_U1, _U2>&& __p) - noexcept(is_nothrow_constructible::value && - is_nothrow_constructible::value) - : first(_CUDA_VSTD::move(__p.first)), second(_CUDA_VSTD::move(__p.second)) {} - -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - template::value - >* = nullptr> - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_HOST constexpr - explicit(!_CheckArgs::template __is_implicit::value) - pair(const ::std::pair<_U1, _U2>&& __p) - noexcept(is_nothrow_constructible::value && - is_nothrow_constructible::value) - : first(_CUDA_VSTD::move(__p.first)), second(_CUDA_VSTD::move(__p.second)) {} -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) -#endif // _CCCL_STD_VER > 2020 +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 && _LIBCUDACXX_TRAIT(is_default_constructible, _T1) + && _LIBCUDACXX_TRAIT(is_default_constructible, _T2); + + static constexpr bool __explicit_constructible_from_elements = + _LIBCUDACXX_TRAIT(is_copy_constructible, _T1) && _LIBCUDACXX_TRAIT(is_copy_constructible, _T2) + && (!_LIBCUDACXX_TRAIT(is_convertible, __make_const_lvalue_ref<_T1>, _T1) + || !_LIBCUDACXX_TRAIT(is_convertible, __make_const_lvalue_ref<_T2>, _T2)); + + static constexpr bool __implicit_constructible_from_elements = + _LIBCUDACXX_TRAIT(is_copy_constructible, _T1) && _LIBCUDACXX_TRAIT(is_copy_constructible, _T2) + && _LIBCUDACXX_TRAIT(is_convertible, __make_const_lvalue_ref<_T1>, _T1) + && _LIBCUDACXX_TRAIT(is_convertible, __make_const_lvalue_ref<_T2>, _T2); + + template + struct __constructible + { + static constexpr bool __explicit_constructible = + _LIBCUDACXX_TRAIT(is_constructible, _T1, _U1) && _LIBCUDACXX_TRAIT(is_constructible, _T2, _U2) + && (!_LIBCUDACXX_TRAIT(is_convertible, _U1, _T1) || !_LIBCUDACXX_TRAIT(is_convertible, _U2, _T2)); + + static constexpr bool __implicit_constructible = + _LIBCUDACXX_TRAIT(is_constructible, _T1, _U1) && _LIBCUDACXX_TRAIT(is_constructible, _T2, _U2) + && _LIBCUDACXX_TRAIT(is_convertible, _U1, _T1) && _LIBCUDACXX_TRAIT(is_convertible, _U2, _T2); + }; + + template + struct __assignable + { + static constexpr bool __enable_assign = + _LIBCUDACXX_TRAIT(is_assignable, _T1&, _U1) && _LIBCUDACXX_TRAIT(is_assignable, _T2&, _U2); + }; +}; - template::template __enable_explicit<_Tuple>::value - >* = nullptr> - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - explicit pair(_Tuple&& __p) - : first(_CUDA_VSTD::get<0>(_CUDA_VSTD::forward<_Tuple>(__p))), - second(_CUDA_VSTD::get<1>(_CUDA_VSTD::forward<_Tuple>(__p))) {} - - template::template __enable_implicit<_Tuple>::value - >* = nullptr> - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - pair(_Tuple&& __p) - : first(_CUDA_VSTD::get<0>(_CUDA_VSTD::forward<_Tuple>(__p))), - second(_CUDA_VSTD::get<1>(_CUDA_VSTD::forward<_Tuple>(__p))) {} - - template - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 - pair(piecewise_construct_t __pc, - tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) - noexcept((is_nothrow_constructible::value && - is_nothrow_constructible::value)) - : pair(__pc, __first_args, __second_args, - __make_tuple_indices_t(), - __make_tuple_indices_t()) {} - - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 - pair& operator=(__conditional_t< - is_copy_assignable::value && - is_copy_assignable::value, - pair, __nat> const& __p) - noexcept(is_nothrow_copy_assignable::value && - is_nothrow_copy_assignable::value) - { - first = __p.first; - second = __p.second; - return *this; - } +// We need to synthesize the copy / move assignment if it would be implicitly deleted as a member of a class +// In that case _T1 would be copy assignable but _TestSynthesizeAssignment<_T1> would not +// This happens e.g for reference types +template +struct _TestSynthesizeAssignment +{ + _T1 __dummy; +}; -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - template::value && - is_copy_assignable<_T2>::value, int> = 0> - _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 - pair& operator=(::std::pair<_T1, _T2> const& __p) - noexcept(is_nothrow_copy_assignable::value && - is_nothrow_copy_assignable::value) - { - first = __p.first; - second = __p.second; - return *this; - } -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) +template +struct __must_synthesize_assignment + : integral_constant) + && _LIBCUDACXX_TRAIT(is_copy_assignable, _TestSynthesizeAssignment<_T2>))) + || (_LIBCUDACXX_TRAIT(is_move_assignable, _T1) && _LIBCUDACXX_TRAIT(is_move_assignable, _T2) + && !(_LIBCUDACXX_TRAIT(is_move_assignable, _TestSynthesizeAssignment<_T1>) + && _LIBCUDACXX_TRAIT(is_move_assignable, _TestSynthesizeAssignment<_T2>)))> +{}; + +// base class to ensure `is_trivially_copyable` when possible +template ::value> +struct __pair_base +{ + _T1 first; + _T2 second; + + template , + __enable_if_t<_Constraints::__explicit_default_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY explicit constexpr __pair_base() noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T1) + && _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T2)) + : first() + , second() + {} + + template , + __enable_if_t<_Constraints::__implicit_default_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY constexpr __pair_base() noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T1) + && _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T2)) + : first() + , second() + {} + + template + _LIBCUDACXX_INLINE_VISIBILITY constexpr __pair_base(_U1&& __t1, _U2&& __t2) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, _U1) && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, _U2)) + : first(_CUDA_VSTD::forward<_U1>(__t1)) + , second(_CUDA_VSTD::forward<_U2>(__t2)) + {} + +protected: + template + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 __pair_base( + piecewise_construct_t, + tuple<_Args1...>& __first_args, + tuple<_Args2...>& __second_args, + __tuple_indices<_I1...>, + __tuple_indices<_I2...>); +}; - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 - pair& operator=(__conditional_t< - is_move_assignable::value && - is_move_assignable::value, - pair, __nat>&& __p) - noexcept(is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value) - { - first = _CUDA_VSTD::forward(__p.first); - second = _CUDA_VSTD::forward(__p.second); - return *this; - } +template +struct __pair_base<_T1, _T2, true> +{ + _T1 first; + _T2 second; + + template , + __enable_if_t<_Constraints::__explicit_default_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY explicit constexpr __pair_base() noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T1) + && _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T2)) + : first() + , second() + {} + + template , + __enable_if_t<_Constraints::__implicit_default_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY constexpr __pair_base() noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T1) + && _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T2)) + : first() + , second() + {} + + constexpr __pair_base(const __pair_base&) = default; + constexpr __pair_base(__pair_base&&) = default; + + // We need to ensure that a reference type, which would inhibit the implicit copy assignment still works + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 __pair_base& operator=( + __conditional_t<_LIBCUDACXX_TRAIT(is_copy_assignable, _T1) && _LIBCUDACXX_TRAIT(is_copy_assignable, _T2), + __pair_base, + __nat> const& __p) noexcept(_LIBCUDACXX_TRAIT(is_nothrow_copy_assignable, _T1) + && _LIBCUDACXX_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 + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 __pair_base& operator=( + __conditional_t<_LIBCUDACXX_TRAIT(is_move_assignable, _T1) && _LIBCUDACXX_TRAIT(is_move_assignable, _T2), + __pair_base, + __nat>&& __p) noexcept(_LIBCUDACXX_TRAIT(is_nothrow_move_assignable, _T1) + && _LIBCUDACXX_TRAIT(is_nothrow_move_assignable, _T2)) + { + first = _CUDA_VSTD::forward<_T1>(__p.first); + second = _CUDA_VSTD::forward<_T2>(__p.second); + return *this; + } + + template + _LIBCUDACXX_INLINE_VISIBILITY constexpr __pair_base(_U1&& __t1, _U2&& __t2) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, _U1) && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, _U2)) + : first(_CUDA_VSTD::forward<_U1>(__t1)) + , second(_CUDA_VSTD::forward<_U2>(__t2)) + {} + +protected: + template + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 __pair_base( + piecewise_construct_t, + tuple<_Args1...>& __first_args, + tuple<_Args2...>& __second_args, + __tuple_indices<_I1...>, + __tuple_indices<_I2...>); +}; +template +struct _LIBCUDACXX_TEMPLATE_VIS pair : public __pair_base<_T1, _T2> +{ + using __base = __pair_base<_T1, _T2>; + + typedef _T1 first_type; + typedef _T2 second_type; + + template , + __enable_if_t<_Constraints::__explicit_default_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY explicit constexpr pair() noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T1) + && _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T2)) + : __base() + {} + + template , + __enable_if_t<_Constraints::__implicit_default_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY constexpr pair() noexcept(_LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T1) + && _LIBCUDACXX_TRAIT(is_nothrow_default_constructible, _T2)) + : __base() + {} + + // element wise constructors + template , + __enable_if_t<_Constraints::__explicit_constructible_from_elements, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY explicit constexpr pair(const _T1& __t1, const _T2& __t2) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_copy_constructible, _T1) && _LIBCUDACXX_TRAIT(is_nothrow_copy_constructible, _T2)) + : __base(__t1, __t2) + {} + + template , + __enable_if_t<_Constraints::__implicit_constructible_from_elements, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY constexpr pair(const _T1& __t1, const _T2& __t2) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_copy_constructible, _T1) && _LIBCUDACXX_TRAIT(is_nothrow_copy_constructible, _T2)) + : __base(__t1, __t2) + {} + + template ::template __constructible<_U1, _U2>, + __enable_if_t<_Constraints::__explicit_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY explicit constexpr pair(_U1&& __u1, _U2&& __u2) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, _U1) && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, _U2)) + : __base(_CUDA_VSTD::forward<_U1>(__u1), _CUDA_VSTD::forward<_U2>(__u2)) + {} + + template ::template __constructible<_U1, _U2>, + __enable_if_t<_Constraints::__implicit_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY constexpr pair(_U1&& __u1, _U2&& __u2) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, _U1) && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, _U2)) + : __base(_CUDA_VSTD::forward<_U1>(__u1), _CUDA_VSTD::forward<_U2>(__u2)) + {} + + template + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 + 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 + pair(pair const&) = default; + pair(pair&&) = default; + + template ::template __constructible, + __enable_if_t<_Constraints::__explicit_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY explicit _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 pair(const pair<_U1, _U2>& __p) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, const _U1&) + && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, const _U2&)) + : __base(__p.first, __p.second) + {} + + template ::template __constructible, + __enable_if_t<_Constraints::__implicit_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 pair(const pair<_U1, _U2>& __p) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, const _U1&) + && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, const _U2&)) + : __base(__p.first, __p.second) + {} + + // move constructors + template ::template __constructible<_U1, _U2>, + __enable_if_t<_Constraints::__explicit_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY explicit _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2>&& __p) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, _U1) && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, _U2)) + : __base(_CUDA_VSTD::forward<_U1>(__p.first), _CUDA_VSTD::forward<_U2>(__p.second)) + {} + + template ::template __constructible<_U1, _U2>, + __enable_if_t<_Constraints::__implicit_constructible, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2>&& __p) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, _U1) && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, _U2)) + : __base(_CUDA_VSTD::forward<_U1>(__p.first), _CUDA_VSTD::forward<_U2>(__p.second)) + {} + + // std compatability +#if defined(__cuda_std__) && !defined(_CCCL_COMPILER_NVRTC) + template ::template __constructible, + __enable_if_t<_Constraints::__explicit_constructible, int> = 0> + _LIBCUDACXX_HOST _LIBCUDACXX_HIDE_FROM_ABI explicit _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 + pair(const ::std::pair<_U1, _U2>& __p) noexcept(_LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, const _U1&) + && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, const _U2&)) + : __base(__p.first, __p.second) + {} + + template ::template __constructible, + __enable_if_t<_Constraints::__implicit_constructible, int> = 0> + _LIBCUDACXX_HOST _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 + pair(const ::std::pair<_U1, _U2>& __p) noexcept(_LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, const _U1&) + && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, const _U2&)) + : __base(__p.first, __p.second) + {} + + template ::template __constructible<_U1, _U2>, + __enable_if_t<_Constraints::__explicit_constructible, int> = 0> + _LIBCUDACXX_HOST _LIBCUDACXX_HIDE_FROM_ABI explicit _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 + pair(::std::pair<_U1, _U2>&& __p) noexcept(_LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, _U1) + && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, _U2)) + : __base(_CUDA_VSTD::forward<_U1>(__p.first), _CUDA_VSTD::forward<_U2>(__p.second)) + {} + + template ::template __constructible<_U1, _U2>, + __enable_if_t<_Constraints::__implicit_constructible, int> = 0> + _LIBCUDACXX_HOST _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 + pair(::std::pair<_U1, _U2>&& __p) noexcept(_LIBCUDACXX_TRAIT(is_nothrow_constructible, _T1, _U1) + && _LIBCUDACXX_TRAIT(is_nothrow_constructible, _T2, _U2)) + : __base(_CUDA_VSTD::forward<_U1>(__p.first), _CUDA_VSTD::forward<_U2>(__p.second)) + {} +#endif // defined(__cuda_std__) && !defined(_CCCL_COMPILER_NVRTC) + + // assignments + pair& operator=(const pair&) = default; + pair& operator=(pair&&) = default; + + template ::template __assignable, + __enable_if_t<_Constraints::__enable_assign, int> = 0> + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 pair& operator=(const pair<_U1, _U2>& __p) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_assignable, _T1, const _U1&) + && _LIBCUDACXX_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_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 pair& operator=(pair<_U1, _U2>&& __p) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_assignable, _T1, _U1) && _LIBCUDACXX_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 defined(__cuda_std__) && !defined(__CUDACC_RTC__) - template::value && - is_move_assignable<_T2>::value, int> = 0> - _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 - pair& operator=(::std::pair<_T1, _T2>&& __p) - noexcept(is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value) - { - first = _CUDA_VSTD::forward(__p.first); - second = _CUDA_VSTD::forward(__p.second); - return *this; - } + template ::value && is_copy_assignable<_T2>::value, int> = 0> + _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 pair& operator=(::std::pair<_T1, _T2> const& __p) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_copy_assignable, _T1) && _LIBCUDACXX_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> + _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 pair& operator=(::std::pair<_T1, _T2>&& __p) noexcept( + _LIBCUDACXX_TRAIT(is_nothrow_copy_assignable, _T1) && _LIBCUDACXX_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 // defined(__cuda_std__) && !defined(__CUDACC_RTC__) #if _CCCL_STD_VER > 2020 - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr - const pair& operator=(pair const& __p) const - noexcept(is_nothrow_copy_assignable_v && - is_nothrow_copy_assignable_v) - requires(is_copy_assignable_v && - is_copy_assignable_v) { - first = __p.first; - second = __p.second; - return *this; - } - -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_HOST constexpr - const pair& operator=(::std::pair<_T1, _T2> const& __p) const - noexcept(is_nothrow_copy_assignable_v && - is_nothrow_copy_assignable_v) - requires(is_copy_assignable_v && - is_copy_assignable_v) { - first = __p.first; - second = __p.second; - return *this; - } -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) - - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr - const pair& operator=(pair&& __p) const - noexcept(is_nothrow_assignable_v && - is_nothrow_assignable_v) - requires(is_assignable_v && - is_assignable_v) { - first = _CUDA_VSTD::forward(__p.first); - second = _CUDA_VSTD::forward(__p.second); - return *this; - } - -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_HOST constexpr - const pair& operator=(::std::pair<_T1, _T2>&& __p) const - noexcept(is_nothrow_assignable_v && - is_nothrow_assignable_v) - requires(is_assignable_v && - is_assignable_v) { - first = _CUDA_VSTD::forward(__p.first); - second = _CUDA_VSTD::forward(__p.second); - return *this; - } -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) - - template - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr - const pair& operator=(const pair<_U1, _U2>& __p) const - requires(is_assignable_v && - is_assignable_v) { - first = __p.first; - second = __p.second; - return *this; - } - -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - template - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_HOST constexpr - const pair& operator=(const ::std::pair<_U1, _U2>& __p) const - requires(is_assignable_v && - is_assignable_v) { - first = __p.first; - second = __p.second; - return *this; - } -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) - - template - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr - const pair& operator=(pair<_U1, _U2>&& __p) const - requires(is_assignable_v && - is_assignable_v) { - first = _CUDA_VSTD::forward<_U1>(__p.first); - second = _CUDA_VSTD::forward<_U2>(__p.second); - return *this; - } - -#if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - template - _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_HOST constexpr - const pair& operator=(::std::pair<_U1, _U2>&& __p) const - requires(is_assignable_v && - is_assignable_v) { - first = _CUDA_VSTD::forward<_U1>(__p.first); - second = _CUDA_VSTD::forward<_U2>(__p.second); - return *this; - } -#endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) + _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr const pair& operator=(pair const& __p) const + noexcept(_LIBCUDACXX_TRAIT(is_nothrow_copy_assignable, const _T1) + && _LIBCUDACXX_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 defined(__cuda_std__) && !defined(__CUDACC_RTC__) + _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_HOST constexpr const pair& operator=(::std::pair<_T1, _T2> const& __p) const + noexcept(_LIBCUDACXX_TRAIT(is_nothrow_copy_assignable, const _T1) + && _LIBCUDACXX_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 // defined(__cuda_std__) && !defined(__CUDACC_RTC__) + + _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr const pair& operator=(pair&& __p) const + noexcept(_LIBCUDACXX_TRAIT(is_nothrow_assignable, const _T1&, _T1) + && _LIBCUDACXX_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 defined(__cuda_std__) && !defined(__CUDACC_RTC__) + _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_HOST constexpr const pair& operator=(::std::pair<_T1, _T2>&& __p) const + noexcept(_LIBCUDACXX_TRAIT(is_nothrow_assignable, const _T1&, _T1) + && _LIBCUDACXX_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 // defined(__cuda_std__) && !defined(__CUDACC_RTC__) + + template + _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY 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 defined(__cuda_std__) && !defined(__CUDACC_RTC__) + template + _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_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 // defined(__cuda_std__) && !defined(__CUDACC_RTC__) + + template + _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY 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 defined(__cuda_std__) && !defined(__CUDACC_RTC__) + template + _LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_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 // defined(__cuda_std__) && !defined(__CUDACC_RTC__) #endif // _CCCL_STD_VER > 2020 - template ::template __enable_assign<_Tuple>::value - >* = nullptr> - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 - pair& operator=(_Tuple&& __p) { - first = _CUDA_VSTD::get<0>(_CUDA_VSTD::forward<_Tuple>(__p)); - second = _CUDA_VSTD::get<1>(_CUDA_VSTD::forward<_Tuple>(__p)); - return *this; - } - - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 - void swap(pair& __p) noexcept(__is_nothrow_swappable::value && - __is_nothrow_swappable::value) - { - using _CUDA_VSTD::swap; - swap(first, __p.first); - swap(second, __p.second); - } + _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 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 > 2020 - _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(first, __p.first); - swap(second, __p.second); - } + _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 > 2020 #if defined(__cuda_std__) && !defined(__CUDACC_RTC__) - _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - operator ::std::pair<_T1, _T2>() const { return { first, second }; } + _LIBCUDACXX_HOST _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 operator ::std::pair<_T1, _T2>() const + { + return {this->first, this->second}; + } #endif // defined(__cuda_std__) && !defined(__CUDACC_RTC__) - -private: - - template - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 - pair(piecewise_construct_t, - tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, - __tuple_indices<_I1...>, __tuple_indices<_I2...>); }; #if _CCCL_STD_VER > 2014 && !defined(_LIBCUDACXX_HAS_NO_DEDUCTION_GUIDES) -template +template _LIBCUDACXX_HOST_DEVICE pair(_T1, _T2) -> pair<_T1, _T2>; #endif // _CCCL_STD_VER > 2014 && !defined(_LIBCUDACXX_HAS_NO_DEDUCTION_GUIDES) // [pairs.spec], specialized algorithms template -inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 -bool -operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) +inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 bool +operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { - return __x.first == __y.first && __x.second == __y.second; + return __x.first == __y.first && __x.second == __y.second; } #ifndef _LIBCUDACXX_HAS_NO_SPACESHIP_OPERATOR template -_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY 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); +_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY 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_NO_SPACESHIP_OPERATOR template -inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 -bool -operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) +inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 bool +operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { - return !(__x == __y); + return !(__x == __y); } template -inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 -bool -operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) +inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 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); + return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second); } template -inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 -bool -operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) +inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 bool +operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { - return __y < __x; + return __y < __x; } template -inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 -bool -operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) +inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 bool +operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { - return !(__x < __y); + return !(__x < __y); } template -inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 -bool -operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) +inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 bool +operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) { - return !(__y < __x); + return !(__y < __x); } #endif // _LIBCUDACXX_HAS_NO_SPACESHIP_OPERATOR #if _CCCL_STD_VER > 2017 -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 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>>; + 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 > 2017 template -inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 -__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); +inline _LIBCUDACXX_INLINE_VISIBILITY + _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 __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 > 2020 template - requires (__is_swappable::value && - __is_swappable::value) -_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr -void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) - noexcept(noexcept(__x.swap(__y))) + requires(__is_swappable::value && __is_swappable::value) +_LIBCUDACXX_HIDE_FROM_ABI _LIBCUDACXX_INLINE_VISIBILITY constexpr void +swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(noexcept(__x.swap(__y))) { - __x.swap(__y); + __x.swap(__y); } #endif // _CCCL_STD_VER > 2020 template inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 -pair::type, typename __unwrap_ref_decay<_T2>::type> -make_pair(_T1&& __t1, _T2&& __t2) + 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)); + return pair::type, typename __unwrap_ref_decay<_T2>::type>( + _CUDA_VSTD::forward<_T1>(__t1), _CUDA_VSTD::forward<_T2>(__t2)); } template - struct _LIBCUDACXX_TEMPLATE_VIS tuple_size > - : public integral_constant {}; +struct _LIBCUDACXX_TEMPLATE_VIS tuple_size > : public integral_constant +{}; template struct _LIBCUDACXX_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> > { - static_assert(_Ip < 2, "Index out of bounds in std::tuple_element>"); + static_assert(_Ip < 2, "Index out of bounds in std::tuple_element>"); }; template struct _LIBCUDACXX_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > { - typedef _LIBCUDACXX_NODEBUG_TYPE _T1 type; + typedef _LIBCUDACXX_NODEBUG_TYPE _T1 type; }; template struct _LIBCUDACXX_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > { - typedef _LIBCUDACXX_NODEBUG_TYPE _T2 type; + typedef _LIBCUDACXX_NODEBUG_TYPE _T2 type; }; -template struct __get_pair; +template +struct __get_pair; template <> struct __get_pair<0> { - template - static - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - _T1& - get(pair<_T1, _T2>& __p) noexcept {return __p.first;} - - template - static - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - const _T1& - get(const pair<_T1, _T2>& __p) noexcept {return __p.first;} - - template - static - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - _T1&& - get(pair<_T1, _T2>&& __p) noexcept {return _CUDA_VSTD::forward<_T1>(__p.first);} - - template - static - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - const _T1&& - get(const pair<_T1, _T2>&& __p) noexcept {return _CUDA_VSTD::forward(__p.first);} + template + static _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 _T1& get(pair<_T1, _T2>& __p) noexcept + { + return __p.first; + } + + template + static _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 const _T1& + get(const pair<_T1, _T2>& __p) noexcept + { + return __p.first; + } + + template + static _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 _T1&& get(pair<_T1, _T2>&& __p) noexcept + { + return _CUDA_VSTD::forward<_T1>(__p.first); + } + + template + static _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 const _T1&& + get(const pair<_T1, _T2>&& __p) noexcept + { + return _CUDA_VSTD::forward(__p.first); + } }; template <> struct __get_pair<1> { - template - static - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - _T2& - get(pair<_T1, _T2>& __p) noexcept {return __p.second;} - - template - static - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - const _T2& - get(const pair<_T1, _T2>& __p) noexcept {return __p.second;} - - template - static - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - _T2&& - get(pair<_T1, _T2>&& __p) noexcept {return _CUDA_VSTD::forward<_T2>(__p.second);} - - template - static - _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 - const _T2&& - get(const pair<_T1, _T2>&& __p) noexcept {return _CUDA_VSTD::forward(__p.second);} + template + static _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 _T2& get(pair<_T1, _T2>& __p) noexcept + { + return __p.second; + } + + template + static _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 const _T2& + get(const pair<_T1, _T2>& __p) noexcept + { + return __p.second; + } + + template + static _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 _T2&& get(pair<_T1, _T2>&& __p) noexcept + { + return _CUDA_VSTD::forward<_T2>(__p.second); + } + + template + static _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 const _T2&& + get(const pair<_T1, _T2>&& __p) noexcept + { + return _CUDA_VSTD::forward(__p.second); + } }; template @@ -790,71 +780,63 @@ template inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 __tuple_element_t<_Ip, pair<_T1, _T2>>&& get(pair<_T1, _T2>&& __p) noexcept { - return __get_pair<_Ip>::get(_CUDA_VSTD::move(__p)); + return __get_pair<_Ip>::get(_CUDA_VSTD::move(__p)); } template inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX11 const __tuple_element_t<_Ip, pair<_T1, _T2>>&& get(const pair<_T1, _T2>&& __p) noexcept { - return __get_pair<_Ip>::get(_CUDA_VSTD::move(__p)); + return __get_pair<_Ip>::get(_CUDA_VSTD::move(__p)); } #if _CCCL_STD_VER > 2011 template -inline _LIBCUDACXX_INLINE_VISIBILITY -constexpr _T1 & get(pair<_T1, _T2>& __p) noexcept +inline _LIBCUDACXX_INLINE_VISIBILITY constexpr _T1& get(pair<_T1, _T2>& __p) noexcept { - return __get_pair<0>::get(__p); + return __get_pair<0>::get(__p); } template -inline _LIBCUDACXX_INLINE_VISIBILITY -constexpr _T1 const & get(pair<_T1, _T2> const& __p) noexcept +inline _LIBCUDACXX_INLINE_VISIBILITY constexpr _T1 const& get(pair<_T1, _T2> const& __p) noexcept { - return __get_pair<0>::get(__p); + return __get_pair<0>::get(__p); } template -inline _LIBCUDACXX_INLINE_VISIBILITY -constexpr _T1 && get(pair<_T1, _T2>&& __p) noexcept +inline _LIBCUDACXX_INLINE_VISIBILITY constexpr _T1&& get(pair<_T1, _T2>&& __p) noexcept { - return __get_pair<0>::get(_CUDA_VSTD::move(__p)); + return __get_pair<0>::get(_CUDA_VSTD::move(__p)); } template -inline _LIBCUDACXX_INLINE_VISIBILITY -constexpr _T1 const && get(pair<_T1, _T2> const&& __p) noexcept +inline _LIBCUDACXX_INLINE_VISIBILITY constexpr _T1 const&& get(pair<_T1, _T2> const&& __p) noexcept { - return __get_pair<0>::get(_CUDA_VSTD::move(__p)); + return __get_pair<0>::get(_CUDA_VSTD::move(__p)); } template -inline _LIBCUDACXX_INLINE_VISIBILITY -constexpr _T1 & get(pair<_T2, _T1>& __p) noexcept +inline _LIBCUDACXX_INLINE_VISIBILITY constexpr _T1& get(pair<_T2, _T1>& __p) noexcept { - return __get_pair<1>::get(__p); + return __get_pair<1>::get(__p); } template -inline _LIBCUDACXX_INLINE_VISIBILITY -constexpr _T1 const & get(pair<_T2, _T1> const& __p) noexcept +inline _LIBCUDACXX_INLINE_VISIBILITY constexpr _T1 const& get(pair<_T2, _T1> const& __p) noexcept { - return __get_pair<1>::get(__p); + return __get_pair<1>::get(__p); } template -inline _LIBCUDACXX_INLINE_VISIBILITY -constexpr _T1 && get(pair<_T2, _T1>&& __p) noexcept +inline _LIBCUDACXX_INLINE_VISIBILITY constexpr _T1&& get(pair<_T2, _T1>&& __p) noexcept { - return __get_pair<1>::get(_CUDA_VSTD::move(__p)); + return __get_pair<1>::get(_CUDA_VSTD::move(__p)); } template -inline _LIBCUDACXX_INLINE_VISIBILITY -constexpr _T1 const && get(pair<_T2, _T1> const&& __p) noexcept +inline _LIBCUDACXX_INLINE_VISIBILITY constexpr _T1 const&& get(pair<_T2, _T1> const&& __p) noexcept { - return __get_pair<1>::get(_CUDA_VSTD::move(__p)); + return __get_pair<1>::get(_CUDA_VSTD::move(__p)); } #endif // _CCCL_STD_VER > 2011 diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/tuple b/libcudacxx/include/cuda/std/detail/libcxx/include/tuple index 7d0382d0794..4847aea15d8 100644 --- a/libcudacxx/include/cuda/std/detail/libcxx/include/tuple +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/tuple @@ -1327,16 +1327,17 @@ template struct _LIBCUDACXX_TEMPLATE_VIS uses_allocator, _Alloc> : true_type {}; -template +template template -inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 -pair<_T1, _T2>::pair(piecewise_construct_t, tuple<_Args1...> &__first_args, - tuple<_Args2...> &__second_args, __tuple_indices<_I1...>, - __tuple_indices<_I2...>) - : first(_CUDA_VSTD::forward<_Args1>(_CUDA_VSTD::get<_I1>(__first_args))...), - second( - _CUDA_VSTD::forward<_Args2>(_CUDA_VSTD::get<_I2>(__second_args))...) { -} +inline _LIBCUDACXX_INLINE_VISIBILITY _LIBCUDACXX_CONSTEXPR_AFTER_CXX17 __pair_base<_T1, _T2, _IsRef>::__pair_base( + piecewise_construct_t, + tuple<_Args1...>& __first_args, + tuple<_Args2...>& __second_args, + __tuple_indices<_I1...>, + __tuple_indices<_I2...>) + : first(_CUDA_VSTD::forward<_Args1>(_CUDA_VSTD::get<_I1>(__first_args))...) + , second(_CUDA_VSTD::forward<_Args2>(_CUDA_VSTD::get<_I2>(__second_args))...) +{} #if _CCCL_STD_VER > 2014 #define _LIBCUDACXX_NOEXCEPT_RETURN(...) \ diff --git a/libcudacxx/include/cuda/std/detail/libcxx/include/type_traits b/libcudacxx/include/cuda/std/detail/libcxx/include/type_traits index 20a51a69551..126035f0084 100644 --- a/libcudacxx/include/cuda/std/detail/libcxx/include/type_traits +++ b/libcudacxx/include/cuda/std/detail/libcxx/include/type_traits @@ -423,6 +423,7 @@ namespace std #endif // __cuda_std__ #include "__assert" // all public C++ headers provide the assertion handler +#include "__fwd/pair.h" #include "__functional/identity.h" #include "__functional/invoke.h" #include "__memory/addressof.h" @@ -571,7 +572,6 @@ namespace std _LIBCUDACXX_BEGIN_NAMESPACE_STD -template struct _LIBCUDACXX_TEMPLATE_VIS pair; template class _LIBCUDACXX_TEMPLATE_VIS reference_wrapper; template struct _LIBCUDACXX_TEMPLATE_VIS hash; diff --git a/libcudacxx/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp b/libcudacxx/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp deleted file mode 100644 index 2c9e2ec2cf5..00000000000 --- a/libcudacxx/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp +++ /dev/null @@ -1,162 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// The test suite needs to define the ABI macros on the command line when -// modules are enabled. -// UNSUPPORTED: -fmodules - -// - -// template struct pair - -// Test that we properly provide the trivial copy operations by default. - -// FreeBSD provides the old ABI. This test checks the new ABI so we need -// to manually turn it on. -#undef _LIBCUDACXX_ABI_UNSTABLE -#undef _LIBCUDACXX_ABI_VERSION -#define _LIBCUDACXX_ABI_VERSION 1 -#define _LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR - -#include -#include -#include -#include -#include - -#include "test_macros.h" - -#if !defined(_LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) -#error trivial ctor ABI macro defined -#endif - -template -struct HasNonTrivialABI : std::integral_constant::value - || (std::is_copy_constructible::value && !std::is_trivially_copy_constructible::value) -#if TEST_STD_VER >= 2011 - || (std::is_move_constructible::value && !std::is_trivially_move_constructible::value) -#endif -> {}; - -#if TEST_STD_VER >= 2011 -struct NonTrivialDtor { - NonTrivialDtor(NonTrivialDtor const&) = default; - ~NonTrivialDtor(); -}; -NonTrivialDtor::~NonTrivialDtor() {} -static_assert(HasNonTrivialABI::value, ""); - -struct NonTrivialCopy { - NonTrivialCopy(NonTrivialCopy const&); -}; -NonTrivialCopy::NonTrivialCopy(NonTrivialCopy const&) {} -static_assert(HasNonTrivialABI::value, ""); - -struct NonTrivialMove { - NonTrivialMove(NonTrivialMove const&) = default; - NonTrivialMove(NonTrivialMove&&); -}; -NonTrivialMove::NonTrivialMove(NonTrivialMove&&) {} -static_assert(HasNonTrivialABI::value, ""); - -struct DeletedCopy { - DeletedCopy(DeletedCopy const&) = delete; - DeletedCopy(DeletedCopy&&) = default; -}; -static_assert(!HasNonTrivialABI::value, ""); - -struct TrivialMove { - TrivialMove(TrivialMove &&) = default; -}; -static_assert(!HasNonTrivialABI::value, ""); - -struct Trivial { - Trivial(Trivial const&) = default; -}; -static_assert(!HasNonTrivialABI::value, ""); -#endif - - -void test_trivial() -{ - { - typedef std::pair P; - static_assert(std::is_copy_constructible

::value, ""); - static_assert(HasNonTrivialABI

::value, ""); - } -#if TEST_STD_VER >= 2011 - { - typedef std::pair P; - static_assert(std::is_move_constructible

::value, ""); - static_assert(HasNonTrivialABI

::value, ""); - } - { - using P = std::pair; - static_assert(!std::is_trivially_destructible

::value, ""); - static_assert(std::is_copy_constructible

::value, ""); - static_assert(!std::is_trivially_copy_constructible

::value, ""); - static_assert(std::is_move_constructible

::value, ""); - static_assert(!std::is_trivially_move_constructible

::value, ""); - static_assert(HasNonTrivialABI

::value, ""); - } - { - using P = std::pair; - static_assert(std::is_copy_constructible

::value, ""); - static_assert(!std::is_trivially_copy_constructible

::value, ""); - static_assert(std::is_move_constructible

::value, ""); - static_assert(!std::is_trivially_move_constructible

::value, ""); - static_assert(HasNonTrivialABI

::value, ""); - } - { - using P = std::pair; - static_assert(std::is_copy_constructible

::value, ""); - static_assert(!std::is_trivially_copy_constructible

::value, ""); - static_assert(std::is_move_constructible

::value, ""); - static_assert(!std::is_trivially_move_constructible

::value, ""); - static_assert(HasNonTrivialABI

::value, ""); - } - { - using P = std::pair; - static_assert(!std::is_copy_constructible

::value, ""); - static_assert(!std::is_trivially_copy_constructible

::value, ""); - static_assert(std::is_move_constructible

::value, ""); - static_assert(!std::is_trivially_move_constructible

::value, ""); - static_assert(HasNonTrivialABI

::value, ""); - } - { - using P = std::pair; - static_assert(std::is_copy_constructible

::value, ""); - static_assert(!std::is_trivially_copy_constructible

::value, ""); - static_assert(std::is_move_constructible

::value, ""); - static_assert(!std::is_trivially_move_constructible

::value, ""); - static_assert(HasNonTrivialABI

::value, ""); - } - { - using P = std::pair; - static_assert(!std::is_copy_constructible

::value, ""); - static_assert(!std::is_trivially_copy_constructible

::value, ""); - static_assert(std::is_move_constructible

::value, ""); - static_assert(!std::is_trivially_move_constructible

::value, ""); - static_assert(HasNonTrivialABI

::value, ""); - } -#endif -} - -void test_layout() { - typedef std::pair, char> PairT; - static_assert(sizeof(PairT) == 3, ""); - static_assert(TEST_ALIGNOF(PairT) == TEST_ALIGNOF(char), ""); - static_assert(offsetof(PairT, first) == 0, ""); -} - -int main(int, char**) { - test_trivial(); - test_layout(); - return 0; -} diff --git a/libcudacxx/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp b/libcudacxx/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp index 55b6d92adf4..3b9558aa928 100644 --- a/libcudacxx/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp +++ b/libcudacxx/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp @@ -26,10 +26,6 @@ #include "test_macros.h" -#if defined(_LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) -#error Non-trivial ctor ABI macro defined -#endif - template struct HasTrivialABI : std::integral_constant::value diff --git a/libcudacxx/libcxx/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp b/libcudacxx/libcxx/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp index c5824165ca7..b221254afa1 100644 --- a/libcudacxx/libcxx/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp +++ b/libcudacxx/libcxx/test/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp @@ -28,25 +28,19 @@ int main(int, char**) typedef std::pair P; { static_assert(std::is_copy_constructible

::value, ""); -#if !defined(_LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) static_assert(std::is_trivially_copy_constructible

::value, ""); -#endif } #if TEST_STD_VER >= 2011 { static_assert(std::is_move_constructible

::value, ""); -#if !defined(_LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) static_assert(std::is_trivially_move_constructible

::value, ""); -#endif } { using P1 = std::pair; static_assert(!std::is_copy_constructible::value, ""); static_assert(!std::is_trivially_copy_constructible::value, ""); static_assert(std::is_move_constructible::value, ""); -#if !defined(_LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) static_assert(std::is_trivially_move_constructible::value, ""); -#endif } #endif diff --git a/libcudacxx/test/libcudacxx/std/utilities/optional/optional.object/special_members.pass.cpp b/libcudacxx/test/libcudacxx/std/utilities/optional/optional.object/special_members.pass.cpp index 4669be0801a..702adbb0e22 100644 --- a/libcudacxx/test/libcudacxx/std/utilities/optional/optional.object/special_members.pass.cpp +++ b/libcudacxx/test/libcudacxx/std/utilities/optional/optional.object/special_members.pass.cpp @@ -9,9 +9,6 @@ // UNSUPPORTED: c++03, c++11 -// UNSUPPORTED: nvrtc -// see nvbug4263883 - // // Make sure we properly generate special member functions for optional diff --git a/libcudacxx/test/libcudacxx/std/utilities/optional/optional.object/triviality.pass.cpp b/libcudacxx/test/libcudacxx/std/utilities/optional/optional.object/triviality.pass.cpp index 9e6f0b1e16a..99453731a6a 100644 --- a/libcudacxx/test/libcudacxx/std/utilities/optional/optional.object/triviality.pass.cpp +++ b/libcudacxx/test/libcudacxx/std/utilities/optional/optional.object/triviality.pass.cpp @@ -9,9 +9,6 @@ // UNSUPPORTED: c++03, c++11 -// UNSUPPORTED: nvrtc -// see nvbug4263883 - // // The following special member functions should propagate the triviality of diff --git a/libcudacxx/test/libcudacxx/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp b/libcudacxx/test/libcudacxx/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp index b1cb0ff34ba..4b5854ffbb5 100644 --- a/libcudacxx/test/libcudacxx/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp +++ b/libcudacxx/test/libcudacxx/std/utilities/utility/pairs/pairs.pair/trivial_copy_move.pass.cpp @@ -30,24 +30,31 @@ int main(int, char**) typedef cuda::std::pair P; { static_assert(cuda::std::is_copy_constructible

::value, ""); -#if !defined(_LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) static_assert(cuda::std::is_trivially_copy_constructible

::value, ""); -#endif } { static_assert(cuda::std::is_move_constructible

::value, ""); -#if !defined(_LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) static_assert(cuda::std::is_trivially_move_constructible

::value, ""); -#endif } { using P1 = cuda::std::pair; static_assert(!cuda::std::is_copy_constructible::value, ""); static_assert(!cuda::std::is_trivially_copy_constructible::value, ""); static_assert(cuda::std::is_move_constructible::value, ""); -#if !defined(_LIBCUDACXX_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) static_assert(cuda::std::is_trivially_move_constructible::value, ""); -#endif + } + + // extensions to ensure pair is trivially_copyable + { + static_assert(cuda::std::is_copy_assignable

::value, ""); + static_assert(cuda::std::is_trivially_copy_assignable

::value, ""); + } + { + static_assert(cuda::std::is_move_assignable

::value, ""); + static_assert(cuda::std::is_trivially_move_assignable

::value, ""); + } + { + static_assert(cuda::std::is_trivially_copyable

::value, ""); } return 0; diff --git a/libcudacxx/test/support/archetypes.ipp b/libcudacxx/test/support/archetypes.ipp index 9066b2b026f..3923f588b18 100644 --- a/libcudacxx/test/support/archetypes.ipp +++ b/libcudacxx/test/support/archetypes.ipp @@ -24,6 +24,13 @@ #define DEFINE_ASSIGN_CONSTEXPR #endif #endif +#ifndef DEFINE_DEFAULT_CONSTEXPR +#if defined(TEST_COMPILER_NVRTC) +#define DEFINE_DEFAULT_CONSTEXPR +#else +#define DEFINE_DEFAULT_CONSTEXPR DEFINE_CONSTEXPR +#endif +#endif #ifndef DEFINE_CTOR #define DEFINE_CTOR = default #undef DEFINE_INIT_LIST // defaulted constructors do not require explicit initializers for the base class @@ -59,7 +66,7 @@ struct AllCtors : DEFINE_BASE(AllCtors) { using Base::Base; #endif using Base::operator=; - DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_DEFAULT_CONSTEXPR AllCtors() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors const&) DEFINE_NOEXCEPT DEFINE_INIT_LIST DEFINE_CTOR; DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR AllCtors(AllCtors &&) DEFINE_NOEXCEPT DEFINE_INIT_LIST DEFINE_CTOR; DEFINE_ASSIGN_ANNOTATIONS DEFINE_ASSIGN_CONSTEXPR AllCtors& operator=(AllCtors const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; @@ -101,7 +108,7 @@ struct DefaultOnly : DEFINE_BASE(DefaultOnly) { #else using Base::Base; #endif - DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR DefaultOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_DEFAULT_CONSTEXPR DefaultOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; DefaultOnly(DefaultOnly const&) DEFINE_NOEXCEPT = delete; DefaultOnly& operator=(DefaultOnly const&) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(DefaultOnly) @@ -118,7 +125,7 @@ struct Copyable : DEFINE_BASE(Copyable) { #else using Base::Base; #endif - DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_DEFAULT_CONSTEXPR Copyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR Copyable(Copyable const &) DEFINE_NOEXCEPT DEFINE_INIT_LIST DEFINE_CTOR; DEFINE_ASSIGN_ANNOTATIONS Copyable &operator=(Copyable const &) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(Copyable) @@ -135,7 +142,7 @@ struct CopyOnly : DEFINE_BASE(CopyOnly) { #else using Base::Base; #endif - DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_DEFAULT_CONSTEXPR CopyOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_INIT_LIST DEFINE_CTOR; DEFINE_EXPLICIT DEFINE_CONSTEXPR CopyOnly(CopyOnly &&) DEFINE_NOEXCEPT = delete; DEFINE_ASSIGN_ANNOTATIONS CopyOnly &operator=(CopyOnly const &) DEFINE_NOEXCEPT DEFINE_ASSIGN; @@ -154,7 +161,7 @@ struct NonCopyable : DEFINE_BASE(NonCopyable) { #else using Base::Base; #endif - DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_DEFAULT_CONSTEXPR NonCopyable() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; DEFINE_EXPLICIT DEFINE_CONSTEXPR NonCopyable(NonCopyable const &) DEFINE_NOEXCEPT = delete; NonCopyable &operator=(NonCopyable const &) DEFINE_NOEXCEPT = delete; DEFINE_DTOR(NonCopyable) @@ -171,7 +178,7 @@ struct MoveOnly : DEFINE_BASE(MoveOnly) { #else using Base::Base; #endif - DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_DEFAULT_CONSTEXPR MoveOnly() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR MoveOnly(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_INIT_LIST DEFINE_CTOR; DEFINE_ASSIGN_ANNOTATIONS MoveOnly &operator=(MoveOnly &&) DEFINE_NOEXCEPT DEFINE_ASSIGN; DEFINE_DTOR(MoveOnly) @@ -233,7 +240,7 @@ struct ConvertingType : DEFINE_BASE(ConvertingType) { #else using Base::Base; #endif - DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; + DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_DEFAULT_CONSTEXPR ConvertingType() DEFINE_NOEXCEPT DEFINE_DEFAULT_CTOR; DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_INIT_LIST DEFINE_CTOR; DEFINE_CTOR_ANNOTATIONS DEFINE_EXPLICIT DEFINE_CONSTEXPR ConvertingType(ConvertingType &&) DEFINE_NOEXCEPT DEFINE_INIT_LIST DEFINE_CTOR; DEFINE_ASSIGN_ANNOTATIONS ConvertingType& operator=(ConvertingType const&) DEFINE_NOEXCEPT DEFINE_ASSIGN; diff --git a/thrust/thrust/system/detail/sequential/partition.h b/thrust/thrust/system/detail/sequential/partition.h index 2c09ea5cb02..15ab47c9fdd 100644 --- a/thrust/thrust/system/detail/sequential/partition.h +++ b/thrust/thrust/system/detail/sequential/partition.h @@ -173,6 +173,11 @@ _CCCL_HOST_DEVICE ForwardIterator last, Predicate pred) { + if (first == last) + { + return first; + } + // wrap pred thrust::detail::wrapped_function< Predicate, diff --git a/thrust/thrust/system/detail/sequential/trivial_copy.h b/thrust/thrust/system/detail/sequential/trivial_copy.h index e4cdea5bc89..5ad1b27d2a9 100644 --- a/thrust/thrust/system/detail/sequential/trivial_copy.h +++ b/thrust/thrust/system/detail/sequential/trivial_copy.h @@ -49,6 +49,13 @@ _CCCL_HOST_DEVICE std::ptrdiff_t n, T *result) { + if (n == 0) + { + // If `first` or `result` is an invalid pointer, + // the behavior of `std::memmove` is undefined, even if `n` is zero. + return result; + } + T* return_value = NULL; NV_IF_TARGET(NV_IS_HOST, (