Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ci/matrix.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ workflows:
# args: '--preset libcudacxx --lit-tests "cuda/utility/basic_any.pass.cpp"' }
#
override:
# PROOF-OF-MAIN-BREAKAGE (do not merge): build ONLY thrust with old host
# compilers + C++17 on a pristine main checkout. If these fail with the
# thrust::zip_iterator iterator-concept static_asserts (added by #8845),
# main is broken independently of any feature PR.
- {jobs: ['build'], project: 'thrust', std: 17, ctk: '12.0', cxx: ['gcc7', 'msvc14.39']}

pull_request:
# Old CTK: Oldest/newest supported host compilers:
Expand Down
72 changes: 63 additions & 9 deletions libcudacxx/include/cuda/std/__tuple_dir/tuple_constraints.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,23 +324,58 @@ __tuple_select_tuple_like_constructible(__tuple_types<_Types...>, __tuple_indice
// [tuple#cnstr]-29.3: sizeof...(Types) equals sizeof...(UTypes), and
return __select_constructor::__none;
}
else if constexpr ((sizeof...(_Types) == 1) && __is_cuda_std_tuple<remove_cvref_t<_UTuple>>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those constraints were eagerly evaluated by gcc, which should not have happened

&& (is_same_v<_Types, tuple_element_t<_Indices, remove_cvref_t<_UTuple>>> && ...))
else if constexpr (!(is_constructible_v<_Types, decltype(get<_Indices>(::cuda::std::declval<_UTuple>()))> && ...))
{ // [tuple.cnstr]-21.2: is_constructible<Types, decltype(get<I>(std​::​forward<UTuple>(u)))>... is true
// [tuple.cnstr]-25.2: is_constructible<Types, decltype(get<I>(std​::​forward<UTuple>(u)))>... is true
// [tuple.cnstr]-29.4: is_constructible<Types, decltype(get<I>(std​::​forward<UTuple>(u)))>... is true
return __select_constructor::__none;
}
else
{ // [tuple.cnstr]-15: The expression inside explicit is equivalent to:
// [tuple.cnstr]-23: The expression inside explicit is equivalent to:
// !(is_convertible_v<decltype(get<I>(FWD(u))), Types> && ...)
return (is_convertible_v<decltype(get<_Indices>(::cuda::std::declval<_UTuple>())), _Types> && ...)
? __select_constructor::__implicit
: __select_constructor::__explicit;
}
}

_CCCL_EXEC_CHECK_DISABLE
template <class _UTuple, class _Type, size_t _Index>
[[nodiscard]] _CCCL_API _CCCL_CONSTEVAL __select_constructor
__tuple_select_tuple_like_constructible(__tuple_types<_Type>, __tuple_indices<_Index>) noexcept
{
using ::cuda::std::get;
if constexpr (__is_cuda_std_ranges_subrange_v<remove_cvref_t<_UTuple>>)
{ // [tuple#cnstr]-29.2: remove_cvref_t<UTuple> is not a specialization of ranges​::​subrange,
return __select_constructor::__none;
}
else if constexpr (is_same_v<_UTuple, const tuple<_Type>&> || is_same_v<_UTuple, tuple<_Type>&&>)
{ // Prefers the copy/move constructor
return __select_constructor::__none;
}
else if constexpr (!__tuple_like_with_size<_UTuple, 1>)
{ // [tuple#cnstr]-21.1: sizeof...(Types) equals sizeof...(UTypes), and
// [tuple#cnstr]-29.3: sizeof...(Types) equals sizeof...(UTypes), and
return __select_constructor::__none;
}
else if constexpr (__is_cuda_std_tuple<remove_cvref_t<_UTuple>>
&& is_same_v<_Type, tuple_element_t<_Index, remove_cvref_t<_UTuple>>>)
{ // [tuple#cnstr]-21.3: either sizeof...(Types) is not 1
// [tuple#cnstr]-21.3: is_same_v<T, U> is false
return __select_constructor::__none;
}
else if constexpr ((sizeof...(_Types) == 1) && (is_constructible_v<_Types, _UTuple> && ...))
else if constexpr (is_constructible_v<_Type, _UTuple>)
{ // [tuple#cnstr]-21.3: either sizeof...(Types) is not 1, or is_constructible_v<T, _UTuple> are false
// [tuple#cnstr]-29.5: either sizeof...(Types) is not 1, or is_constructible_v<T, _UTuple> are false
return __select_constructor::__none;
}
else if constexpr ((sizeof...(_Types) == 1) && (is_convertible_v<_UTuple, _Types> && ...))
else if constexpr (is_convertible_v<_UTuple, _Type>)
{ // [tuple#cnstr]-21.3: either sizeof...(Types) is not 1, or is_convertible_v<_UTuple, T> are false
// [tuple#cnstr]-29.5: either sizeof...(Types) is not 1, or is_convertible_v<_UTuple, T> are false
return __select_constructor::__none;
}
else if constexpr (!(is_constructible_v<_Types, decltype(get<_Indices>(::cuda::std::declval<_UTuple>()))> && ...))
else if constexpr (!is_constructible_v<_Type, decltype(get<_Index>(::cuda::std::declval<_UTuple>()))>)
{ // [tuple.cnstr]-21.2: is_constructible<Types, decltype(get<I>(std​::​forward<UTuple>(u)))>... is true
// [tuple.cnstr]-25.2: is_constructible<Types, decltype(get<I>(std​::​forward<UTuple>(u)))>... is true
// [tuple.cnstr]-29.4: is_constructible<Types, decltype(get<I>(std​::​forward<UTuple>(u)))>... is true
Expand All @@ -350,7 +385,7 @@ __tuple_select_tuple_like_constructible(__tuple_types<_Types...>, __tuple_indice
{ // [tuple.cnstr]-15: The expression inside explicit is equivalent to:
// [tuple.cnstr]-23: The expression inside explicit is equivalent to:
// !(is_convertible_v<decltype(get<I>(FWD(u))), Types> && ...)
return (is_convertible_v<decltype(get<_Indices>(::cuda::std::declval<_UTuple>())), _Types> && ...)
return is_convertible_v<decltype(get<_Index>(::cuda::std::declval<_UTuple>())), _Type>
? __select_constructor::__implicit
: __select_constructor::__explicit;
}
Expand All @@ -361,12 +396,31 @@ inline constexpr __select_constructor __tuple_select_tuple_like_constructible_v
::cuda::std::__tuple_select_tuple_like_constructible<_UTuple>(_TupleTypes{}, _TupleIndices{});

_CCCL_EXEC_CHECK_DISABLE
template <class _UTuple, class... _Types, size_t... _Indices>
template <class _UTuple, class _Type, class... _Types, size_t _Index, size_t... _Indices>
[[nodiscard]] _CCCL_API _CCCL_CONSTEVAL bool
__tuple_nothrow_tuple_like_constructible(__tuple_types<_Types...>, __tuple_indices<_Indices...>) noexcept
__tuple_nothrow_tuple_like_constructible(__tuple_types<_Type, _Types...>, __tuple_indices<_Index, _Indices...>) noexcept
{
using ::cuda::std::get;
return (is_nothrow_constructible_v<_Types, decltype(get<_Indices>(::cuda::std::declval<_UTuple>()))> && ...);
if constexpr (!is_nothrow_constructible_v<_Type, decltype(get<_Index>(::cuda::std::declval<_UTuple>()))>)
{
return false;
}
else if constexpr (sizeof...(_Types) != 0)
{
return ::cuda::std::__tuple_nothrow_tuple_like_constructible<_UTuple>(
__tuple_types<_Types...>{}, __tuple_indices<_Indices...>{});
}
else
{
return true;
}
}

template <class _UTuple>
[[nodiscard]] _CCCL_API _CCCL_CONSTEVAL bool
__tuple_nothrow_tuple_like_constructible(__tuple_types<>, __tuple_indices<>) noexcept
{
return true;
}

template <class _UTuple, class _TupleTypes, class _TupleIndices>
Expand Down
Loading