Skip to content

Commit

Permalink
use generalized concepts portability macros to simplify the range c…
Browse files Browse the repository at this point in the history
…oncept (NVIDIA#3217)

fixes some issues in the concepts portability macros and then re-implements the `range` concept with `_CCCL_REQUIRES_EXPR`
  • Loading branch information
ericniebler authored Jan 2, 2025
1 parent f5dddc4 commit 9200801
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 40 deletions.
4 changes: 2 additions & 2 deletions libcudacxx/include/cuda/std/__concepts/common_with.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ _CCCL_CONCEPT _Common_type_exists = _CCCL_FRAGMENT(__common_type_exists_, _Tp, _
template <class _Tp, class _Up>
_CCCL_CONCEPT_FRAGMENT(__common_type_constructible_,
requires()(requires(_Common_type_exists<_Tp, _Up>),
static_cast<common_type_t<_Tp, _Up>>(_CUDA_VSTD::declval<_Tp>()),
static_cast<common_type_t<_Tp, _Up>>(_CUDA_VSTD::declval<_Up>())));
(static_cast<common_type_t<_Tp, _Up>>(_CUDA_VSTD::declval<_Tp>())),
(static_cast<common_type_t<_Tp, _Up>>(_CUDA_VSTD::declval<_Up>()))));

template <class _Tp, class _Up>
_CCCL_CONCEPT _Common_type_constructible = _CCCL_FRAGMENT(__common_type_constructible_, _Tp, _Up);
Expand Down
51 changes: 23 additions & 28 deletions libcudacxx/include/cuda/std/__concepts/concept_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,10 @@ _CCCL_INLINE_VAR constexpr int __cccl_requires = 0;
# endif // !_CCCL_COMPILER(MSVC)

template <class _Tp, class... _Args>
_LIBCUDACXX_HIDE_FROM_ABI auto __cccl_make_dependent(_Tp*, __cccl_tag<_Args...>*) -> _Tp;
extern _Tp __cccl_make_dependent;

template <class _Impl, class... _Args>
using __cccl_requires_expr_impl =
decltype(__cccl_make_dependent(static_cast<_Impl*>(nullptr), static_cast<__cccl_tag<void, _Args...>*>(nullptr)));
using __cccl_requires_expr_impl = decltype(__cccl_make_dependent<_Impl, _Args...>);

// So that we can refer to the ::cuda::std namespace below
_LIBCUDACXX_BEGIN_NAMESPACE_STD
Expand Down Expand Up @@ -186,9 +185,8 @@ namespace __cccl_unqualified_cuda_std = _CUDA_VSTD; // NOLINT(misc-unused-alias-
# endif
# define _CCCL_CONCEPT_FRAGMENT_REQS_requires(...) (__VA_ARGS__)->__cccl_enable_if_t < _CCCL_CONCEPT_FRAGMENT_REQS_2_
# define _CCCL_CONCEPT_FRAGMENT_REQS_2_(...) _CCCL_CONCEPT_FRAGMENT_TRUE(__VA_ARGS__)
# define _CCCL_CONCEPT_FRAGMENT_REQS_M(_REQ) \
_CCCL_PP_CAT2(_CCCL_CONCEPT_FRAGMENT_REQS_M, _CCCL_PP_IS_PAREN(_REQ)) \
(_REQ),
# define _CCCL_CONCEPT_FRAGMENT_REQS_M(_REQ) \
void(), _CCCL_PP_CAT2(_CCCL_CONCEPT_FRAGMENT_REQS_M, _CCCL_PP_IS_PAREN(_REQ))(_REQ),
# define _CCCL_CONCEPT_FRAGMENT_REQS_REQUIRES_requires(...) ::__cccl_requires<__VA_ARGS__>
# define _CCCL_CONCEPT_FRAGMENT_REQS_REQUIRES_typename(...) static_cast<::__cccl_tag<__VA_ARGS__>*>(nullptr)
# if _CCCL_COMPILER(GCC, <, 14)
Expand Down Expand Up @@ -243,30 +241,27 @@ namespace __cccl_unqualified_cuda_std = _CUDA_VSTD; // NOLINT(misc-unused-alias-
# define _CCCL_REQUIRES_EXPR_EXPAND_TPARAMS(...) _CCCL_PP_FOR_EACH(_CCCL_REQUIRES_EXPR_EXPAND_TPARAM, __VA_ARGS__)

# define _CCCL_REQUIRES_EXPR(_TY, ...) _CCCL_REQUIRES_EXPR_IMPL(_TY, _CCCL_COUNTER(), __VA_ARGS__)
# define _CCCL_REQUIRES_EXPR_IMPL(_TY, _ID, ...) \
::__cccl_requires_expr_impl< \
struct _CCCL_PP_CAT(__cccl_requires_expr_detail_, _ID) _CCCL_REQUIRES_EXPR_EXPAND_TPARAMS \
_TY>::__cccl_is_satisfied(static_cast<::__cccl_tag<void _CCCL_REQUIRES_EXPR_EXPAND_TPARAMS _TY>*>(nullptr), \
static_cast<void (*)(__VA_ARGS__)>(nullptr)); \
struct _CCCL_PP_CAT(__cccl_requires_expr_detail_, _ID) \
{ \
using __cccl_self_t = _CCCL_PP_CAT(__cccl_requires_expr_detail_, _ID); \
template <class _CCCL_REQUIRES_EXPR_TPARAMS _TY> \
# define _CCCL_REQUIRES_EXPR_IMPL(_TY, _ID, ...) \
::__cccl_requires_expr_impl<struct _CCCL_PP_CAT(__cccl_requires_expr_detail_, _ID) \
_CCCL_REQUIRES_EXPR_EXPAND_TPARAMS _TY>:: \
__cccl_is_satisfied(static_cast<::__cccl_tag<void _CCCL_REQUIRES_EXPR_EXPAND_TPARAMS _TY>*>(nullptr), 0); \
struct _CCCL_PP_CAT(__cccl_requires_expr_detail_, _ID) \
{ \
using __cccl_self_t = _CCCL_PP_CAT(__cccl_requires_expr_detail_, _ID); \
template <class _CCCL_REQUIRES_EXPR_TPARAMS _TY> \
_LIBCUDACXX_HIDE_FROM_ABI static auto __cccl_well_formed(__VA_ARGS__) _CCCL_REQUIRES_EXPR_2

# define _CCCL_REQUIRES_EXPR_2(...) \
->decltype(_CCCL_PP_FOR_EACH(_CCCL_CONCEPT_FRAGMENT_REQS_M, __VA_ARGS__) void()) {} \
template <class... _Args, \
class _Sig, \
class = decltype(static_cast<_Sig*>(&__cccl_self_t::__cccl_well_formed<_Args...>))> \
_LIBCUDACXX_HIDE_FROM_ABI static constexpr bool __cccl_is_satisfied(::__cccl_tag<_Args...>*, _Sig*) \
{ \
return true; \
} \
_LIBCUDACXX_HIDE_FROM_ABI static constexpr bool __cccl_is_satisfied(void*, ...) \
{ \
return false; \
} \
# define _CCCL_REQUIRES_EXPR_2(...) \
->decltype(_CCCL_PP_FOR_EACH(_CCCL_CONCEPT_FRAGMENT_REQS_M, __VA_ARGS__) void()) {} \
template <class... _Args, class = decltype(&__cccl_self_t::__cccl_well_formed<_Args...>)> \
_LIBCUDACXX_HIDE_FROM_ABI static constexpr bool __cccl_is_satisfied(::__cccl_tag<_Args...>*, int) \
{ \
return true; \
} \
_LIBCUDACXX_HIDE_FROM_ABI static constexpr bool __cccl_is_satisfied(void*, long) \
{ \
return false; \
} \
}
# endif // ^^^ _CCCL_NO_CONCEPTS ^^^

Expand Down
24 changes: 14 additions & 10 deletions libcudacxx/include/cuda/std/__ranges/concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,19 +142,23 @@ concept viewable_range =
# else // ^^^ !_CCCL_NO_CONCEPTS ^^^ / vvv _CCCL_NO_CONCEPTS vvv
// [range.range]

// clang-format off
template <class _Tp>
_CCCL_CONCEPT_FRAGMENT(
__range_,
requires(_Tp& __t)(typename(decltype(_CUDA_VRANGES::begin(__t))), typename(decltype(_CUDA_VRANGES::end(__t)))));

template <class _Tp>
_CCCL_CONCEPT range = _CCCL_FRAGMENT(__range_, _Tp);
_CCCL_CONCEPT range =
_CCCL_REQUIRES_EXPR((_Tp), _Tp& __t)
(
void(_CUDA_VRANGES::begin(__t)),
void(_CUDA_VRANGES::end(__t))
);

template <class _Tp>
_CCCL_CONCEPT_FRAGMENT(__input_range_, requires()(requires(range<_Tp>), requires(input_iterator<iterator_t<_Tp>>)));

template <class _Tp>
_CCCL_CONCEPT input_range = _CCCL_FRAGMENT(__input_range_, _Tp);
_CCCL_CONCEPT input_range =
_CCCL_REQUIRES_EXPR((_Tp))
(
requires(range<_Tp>),
requires(input_iterator<iterator_t<_Tp>>)
);
// clang-format on

template <class _Range>
_CCCL_CONCEPT_FRAGMENT(
Expand Down

0 comments on commit 9200801

Please sign in to comment.