Skip to content
Open
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
10 changes: 5 additions & 5 deletions libcudacxx/include/cuda/__algorithm/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ using __as_span_t = ::cuda::std::span<::cuda::std::remove_reference_t<::cuda::st
//! @brief A concept that checks if the type can be converted to a `cuda::std::span`.
//! The type must be a contiguous range.
template <typename _Tp>
_CCCL_CONCEPT __spannable = _CCCL_REQUIRES_EXPR((_Tp))( //
requires(::cuda::std::ranges::contiguous_range<_Tp>), //
requires(::cuda::std::convertible_to<_Tp, __as_span_t<_Tp>>));
_CCCL_CONCEPT __spannable = _CCCL_REQUIRES_EXPR((_Tp), _Tp&& __value)( //
_Satisfies(cuda::std::ranges::contiguous_range)::cuda::std::forward<_Tp>(__value), //
_Convertible_to(__as_span_t<_Tp>)::cuda::std::forward<_Tp>(__value));

template <typename _Tp>
using __as_mdspan_t =
Expand All @@ -52,8 +52,8 @@ using __as_mdspan_t =
//! @brief A concept that checks if the type can be converted to a `cuda::std::mdspan`.
//! The type must have a conversion to `__as_mdspan_t<_Tp>`.
template <typename _Tp>
_CCCL_CONCEPT __mdspannable =
_CCCL_REQUIRES_EXPR((_Tp))(requires(::cuda::std::convertible_to<_Tp, __as_mdspan_t<_Tp>>));
_CCCL_CONCEPT __mdspannable = _CCCL_REQUIRES_EXPR((_Tp), _Tp&& __value)( //
_Convertible_to(__as_mdspan_t<_Tp>)::cuda::std::forward<_Tp>(__value));

template <typename _Tp>
[[nodiscard]] _CCCL_HOST_API constexpr auto __as_mdspan(_Tp&& __value) noexcept -> __as_mdspan_t<_Tp>
Expand Down
66 changes: 55 additions & 11 deletions libcudacxx/include/cuda/std/__concepts/concept_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,13 @@ namespace __cccl_unqualified_cuda_std = ::cuda::std; // NOLINT(misc-unused-alias
// - _Satisfies(CONCEPT...) EXPR...
//
// The last 4 are handled below:
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH_requires _CCCL_PP_CASE(REQUIRES)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH_noexcept _CCCL_PP_CASE(NOEXCEPT)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH_typename _CCCL_PP_CASE(TYPENAME)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH__Same_as _CCCL_PP_CASE(SAME_AS)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH__Satisfies _CCCL_PP_CASE(SATISFIES)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH_requires _CCCL_PP_CASE(REQUIRES)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH_noexcept _CCCL_PP_CASE(NOEXCEPT)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH_typename _CCCL_PP_CASE(TYPENAME)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH__Same_as _CCCL_PP_CASE(SAME_AS)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH__Satisfies _CCCL_PP_CASE(SATISFIES)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH__Convertible_to _CCCL_PP_CASE(CONVERTIBLE_TO)
#define _CCCL_CONCEPT_REQUIREMENT_SWITCH__Derived_from _CCCL_PP_CASE(DERIVED_FROM)

// Converts "requires(ARGS...)" to "ARGS..."
#define _CCCL_CONCEPT_EAT_REQUIRES_(...) _CCCL_PP_CAT(_CCCL_CONCEPT_EAT_REQUIRES_, __VA_ARGS__)
Expand Down Expand Up @@ -184,18 +186,42 @@ namespace __cccl_unqualified_cuda_std = ::cuda::std; // NOLINT(misc-unused-alias
_CCCL_PP_CAT(_CCCL, _CCCL_PP_EVAL(_CCCL_PP_FIRST, _CCCL_PP_CAT(_CCCL_CONCEPT_GET_TYPE_FROM_SAME_AS_, __VA_ARGS__)))
#define _CCCL_CONCEPT_GET_TYPE_FROM_SAME_AS__Same_as(...) _PP_EXPAND(__VA_ARGS__),

// Converts "_Satisfies(TYPE) EXPR..." to "EXPR..."
// Converts "_Satisfies(CONCEPT) EXPR..." to "EXPR..."
#define _CCCL_CONCEPT_EAT_SATISFIES_(...) _CCCL_PP_CAT(_CCCL_CONCEPT_EAT_SATISFIES_, __VA_ARGS__)
#define _CCCL_CONCEPT_EAT_SATISFIES__Satisfies(...)

// Converts "_Satisfies(TYPE) EXPR..." to "TYPE" (The ridiculous concatenation of _CCCL
// with _PP_EXPAND(__VA_ARGS__) is the only way to get MSVC's broken preprocessor to do macro
// expansion here.)
// Converts "_Satisfies(CONCEPT) EXPR..." to "CONCEPT" (The ridiculous concatenation of
// _CCCL with _PP_EXPAND(__VA_ARGS__) is the only way to get MSVC's broken preprocessor to
// do macro expansion here.)
#define _CCCL_CONCEPT_GET_CONCEPT_FROM_SATISFIES_(...) \
_CCCL_PP_CAT(_CCCL, \
_CCCL_PP_EVAL(_CCCL_PP_FIRST, _CCCL_PP_CAT(_CCCL_CONCEPT_GET_CONCEPT_FROM_SATISFIES_, __VA_ARGS__)))
#define _CCCL_CONCEPT_GET_CONCEPT_FROM_SATISFIES__Satisfies(...) _PP_EXPAND(__VA_ARGS__),

// Converts "_Convertible_to(TYPE) EXPR..." to "EXPR..."
#define _CCCL_CONCEPT_EAT_CONVERTIBLE_TO_(...) _CCCL_PP_CAT(_CCCL_CONCEPT_EAT_CONVERTIBLE_TO_, __VA_ARGS__)
#define _CCCL_CONCEPT_EAT_CONVERTIBLE_TO__Convertible_to(...)

// Converts "_Convertible_to(TYPE) EXPR..." to "TYPE" (The ridiculous concatenation of
// _CCCL with _PP_EXPAND(__VA_ARGS__) is the only way to get MSVC's broken preprocessor to
// do macro expansion here.)
#define _CCCL_CONCEPT_GET_TYPE_FROM_CONVERTIBLE_TO_(...) \
_CCCL_PP_CAT(_CCCL, \
_CCCL_PP_EVAL(_CCCL_PP_FIRST, _CCCL_PP_CAT(_CCCL_CONCEPT_GET_TYPE_FROM_CONVERTIBLE_TO_, __VA_ARGS__)))
#define _CCCL_CONCEPT_GET_TYPE_FROM_CONVERTIBLE_TO__Convertible_to(...) _PP_EXPAND(__VA_ARGS__),

// Converts "_Derived_from(TYPE) EXPR..." to "EXPR..."
#define _CCCL_CONCEPT_EAT_DERIVED_FROM_(...) _CCCL_PP_CAT(_CCCL_CONCEPT_EAT_DERIVED_FROM_, __VA_ARGS__)
#define _CCCL_CONCEPT_EAT_DERIVED_FROM__Derived_from(...)

// Converts "_Derived_from(TYPE) EXPR..." to "TYPE" (The ridiculous concatenation of
// _CCCL with _PP_EXPAND(__VA_ARGS__) is the only way to get MSVC's broken preprocessor to
// do macro expansion here.)
#define _CCCL_CONCEPT_GET_TYPE_FROM_DERIVED_FROM_(...) \
_CCCL_PP_CAT(_CCCL, \
_CCCL_PP_EVAL(_CCCL_PP_FIRST, _CCCL_PP_CAT(_CCCL_CONCEPT_GET_TYPE_FROM_DERIVED_FROM_, __VA_ARGS__)))
#define _CCCL_CONCEPT_GET_TYPE_FROM_DERIVED_FROM__Derived_from(...) _PP_EXPAND(__VA_ARGS__),

// Here are the implementations of the internal macros, first for when concepts
// are available, and then for when they're not.
#if _CCCL_HAS_CONCEPTS() || defined(_CCCL_DOXYGEN_INVOKED)
Expand All @@ -222,6 +248,12 @@ namespace __cccl_unqualified_cuda_std = ::cuda::std; // NOLINT(misc-unused-alias
{_CCCL_CONCEPT_EAT_SAME_AS_(_REQ)}->_CCCL_CONCEPT_VSTD::same_as<_CCCL_CONCEPT_GET_TYPE_FROM_SAME_AS_(_REQ)>
# define _CCCL_CONCEPT_REQUIREMENT_CASE_SATISFIES(_REQ) \
{_CCCL_CONCEPT_EAT_SATISFIES_(_REQ)}->_CCCL_CONCEPT_GET_CONCEPT_FROM_SATISFIES_(_REQ)
# define _CCCL_CONCEPT_REQUIREMENT_CASE_CONVERTIBLE_TO(_REQ) \
{_CCCL_CONCEPT_EAT_CONVERTIBLE_TO_(_REQ)} \
->_CCCL_CONCEPT_VSTD::convertible_to<_CCCL_CONCEPT_GET_TYPE_FROM_CONVERTIBLE_TO_(_REQ)>
# define _CCCL_CONCEPT_REQUIREMENT_CASE_DERIVED_FROM(_REQ) \
{_CCCL_CONCEPT_EAT_DERIVED_FROM_(_REQ)} \
->_CCCL_CONCEPT_VSTD::derived_from<_CCCL_CONCEPT_GET_TYPE_FROM_DERIVED_FROM_(_REQ)>

# define _CCCL_FRAGMENT(_NAME, ...) _NAME<__VA_ARGS__>

Expand Down Expand Up @@ -269,10 +301,22 @@ namespace __cccl_unqualified_cuda_std = ::cuda::std; // NOLINT(misc-unused-alias
# define _CCCL_CONCEPT_REQUIREMENT_CASE_SATISFIES(_REQ) \
::__cccl_requires < _CCCL_CONCEPT_GET_CONCEPT_FROM_SATISFIES_(_REQ) < decltype(_CCCL_CONCEPT_EAT_SATISFIES_(_REQ)) \
>>
# define _CCCL_CONCEPT_REQUIREMENT_CASE_CONVERTIBLE_TO(_REQ) \
::__cccl_requires<::cuda::std::convertible_to<_CCCL_CONCEPT_CONVERTIBLE_TO_REQUIREMENT_(_REQ)>>
# define _CCCL_CONCEPT_REQUIREMENT_CASE_DERIVED_FROM(_REQ) \
::__cccl_requires<::cuda::std::derived_from<_CCCL_CONCEPT_DERIVED_FROM_REQUIREMENT_(_REQ)>>

// Converts "_Same_as(TYPE) EXPR..." to "TYPE, decltype(EXPR...)"
// Converts "_Same_as(TYPE) EXPR..." to "decltype(EXPR...), TYPE"
# define _CCCL_CONCEPT_SAME_AS_REQUIREMENT_(_REQ) \
_CCCL_CONCEPT_GET_TYPE_FROM_SAME_AS_(_REQ), decltype(_CCCL_CONCEPT_EAT_SAME_AS_(_REQ))
decltype(_CCCL_CONCEPT_EAT_SAME_AS_(_REQ)), _CCCL_CONCEPT_GET_TYPE_FROM_SAME_AS_(_REQ)
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.

Why the swap?

Copy link
Copy Markdown
Contributor Author

@ericniebler ericniebler May 1, 2026

Choose a reason for hiding this comment

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

Just for consistency with the argument order for the _Derived_from and _Convertible_to cases


// Converts "_Convertible_to(TYPE) EXPR..." to "decltype(EXPR...), TYPE"
# define _CCCL_CONCEPT_CONVERTIBLE_TO_REQUIREMENT_(_REQ) \
decltype(_CCCL_CONCEPT_EAT_CONVERTIBLE_TO_(_REQ)), _CCCL_CONCEPT_GET_TYPE_FROM_CONVERTIBLE_TO_(_REQ)

// Converts "_Derived_from(TYPE) EXPR..." to "decltype(EXPR...), TYPE"
# define _CCCL_CONCEPT_DERIVED_FROM_REQUIREMENT_(_REQ) \
decltype(_CCCL_CONCEPT_EAT_DERIVED_FROM_(_REQ)), _CCCL_CONCEPT_GET_TYPE_FROM_DERIVED_FROM_(_REQ)

# if _CCCL_HAS_NOEXCEPT_MANGLING()
// Converts "noexcept(EXPR)" to "::__cccl_requires<noexcept(EXPR)>"
Expand Down
Loading