Skip to content

Commit

Permalink
minor consistency improvements in concepts macros (#2928)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericniebler authored Nov 24, 2024
1 parent c22af18 commit 80031e2
Showing 1 changed file with 52 additions and 55 deletions.
107 changes: 52 additions & 55 deletions libcudacxx/include/cuda/std/__concepts/concept_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
# pragma system_header
#endif // no system header

#include <cuda/std/cstddef> // for size_t

////////////////////////////////////////////////////////////////////////////////
// _CCCL_TEMPLATE
// Usage:
Expand All @@ -50,51 +52,46 @@ using __cccl_enable_if_t = typename __cccl_select<_Bp>::template type<_Tp>;
template <class _Tp, bool _Bp>
using __cccl_requires_t = typename __cccl_select<_Bp>::template type<_Tp>;

#if (defined(__cpp_concepts) && _CCCL_STD_VER >= 2020)
#if (defined(__cpp_concepts) && _CCCL_STD_VER >= 2020) || defined(_CCCL_DOXYGEN_INVOKED)
# define _CCCL_TEMPLATE(...) template <__VA_ARGS__>
# define _CCCL_REQUIRES(...) requires __VA_ARGS__
# define _CCCL_AND &&
# define _CCCL_TRAILING_REQUIRES_AUX_(...) requires __VA_ARGS__
# define _CCCL_TRAILING_REQUIRES(...) ->__VA_ARGS__ _CCCL_TRAILING_REQUIRES_AUX_
#else // ^^^ __cpp_concepts ^^^ / vvv !__cpp_concepts vvv
# define _CCCL_TEMPLATE(...) template <__VA_ARGS__
# define _CCCL_REQUIRES(...) , bool _CCCL_true_ = true, __cccl_enable_if_t < __VA_ARGS__ && _CCCL_true_, int > = 0 >
# define _CCCL_AND &&_CCCL_true_, int > = 0, __cccl_enable_if_t <
# define _CCCL_REQUIRES(...) , bool __cccl_true_ = true, __cccl_enable_if_t < __VA_ARGS__ && __cccl_true_, int > = 0 >
# define _CCCL_AND &&__cccl_true_, int > = 0, __cccl_enable_if_t <
# define _CCCL_TRAILING_REQUIRES_AUX_(...) , __VA_ARGS__ >
# define _CCCL_TRAILING_REQUIRES(...) ->__cccl_requires_t < __VA_ARGS__ _CCCL_TRAILING_REQUIRES_AUX_
#endif // !__cpp_concepts

#if _CCCL_STD_VER >= 2014

namespace __cccl_concept
{

template <typename...>
struct _Tag;
template <class...>
struct __cccl_tag;

template <class>
_LIBCUDACXX_HIDE_FROM_ABI constexpr bool __is_true()
_LIBCUDACXX_HIDE_FROM_ABI constexpr bool __cccl_is_true()
{
return true;
}

# if _CCCL_COMPILER(CLANG) || _CCCL_COMPILER(MSVC)
# if _CCCL_COMPILER(MSVC)
template <bool _Bp>
_LIBCUDACXX_HIDE_FROM_ABI __cccl_enable_if_t<_Bp> __cccl_requires()
{}
# else // ^^^ _CCCL_COMPILER(CLANG) || _CCCL_COMPILER(MSVC) ^^^ / vvv other compilers vvv
# else // ^^^ _CCCL_COMPILER(MSVC) ^^^ / vvv !_CCCL_COMPILER(MSVC) vvv
template <bool _Bp, __cccl_enable_if_t<_Bp, int> = 0>
_CCCL_INLINE_VAR constexpr int __cccl_requires = 0;
# endif // !_CCCL_COMPILER(CLANG) && !_CCCL_COMPILER(MSVC)
# endif // !_CCCL_COMPILER(MSVC)

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

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

} // namespace __cccl_concept
using __cccl_requires_expr_impl =
decltype(__cccl_make_dependent(static_cast<_Impl*>(nullptr), static_cast<__cccl_tag<void, _Args...>*>(nullptr)));

// So that we can refer to the ::cuda::std namespace below
_LIBCUDACXX_BEGIN_NAMESPACE_STD
Expand All @@ -107,21 +104,21 @@ _LIBCUDACXX_END_NAMESPACE_STD
//
// where ::concept is a fully qualified name, would not compile. The
// _CUDA_VSTD macro is fully qualified.
namespace __unqualified_cuda_std = _CUDA_VSTD; // NOLINT(misc-unused-alias-decls)
namespace __cccl_unqualified_cuda_std = _CUDA_VSTD; // NOLINT(misc-unused-alias-decls)

# if _CCCL_CUDACC_BELOW(12, 2)
# define _CCCL_CONCEPT_VSTD __unqualified_cuda_std // must not be fully qualified
# define _CCCL_CONCEPT_VSTD __cccl_unqualified_cuda_std // must not be fully qualified
# else
# define _CCCL_CONCEPT_VSTD _CUDA_VSTD
# endif

# define _CCCL_CONCEPT_FRAGMENT_REQS_M0(_REQ) _CCCL_CONCEPT_FRAGMENT_REQS_SELECT_(_REQ)(_REQ)
# define _CCCL_CONCEPT_FRAGMENT_REQS_M1(_REQ) _CCCL_PP_EXPAND _REQ
# define _CCCL_CONCEPT_FRAGMENT_REQS_(...) {_CCCL_PP_FOR_EACH(_CCCL_CONCEPT_FRAGMENT_REQS_M, __VA_ARGS__)}
# define _CCCL_CONCEPT_FRAGMENT_REQS_SELECT_(_REQ) \
_CCCL_PP_CAT3(_CCCL_CONCEPT_FRAGMENT_REQS_SELECT_, \
_CCCL_PP_EVAL(_CCCL_PP_CHECK, _CCCL_PP_CAT3(_CCCL_CONCEPT_FRAGMENT_REQS_SELECT_PROBE_, _REQ))) \
/**/
# define _CCCL_CONCEPT_FRAGMENT_REQS_SELECT_(_REQ) \
_CCCL_PP_CAT3(_CCCL_CONCEPT_FRAGMENT_REQS_SELECT_, \
_CCCL_PP_EVAL(_CCCL_PP_CHECK, _CCCL_PP_CAT3(_CCCL_CONCEPT_FRAGMENT_REQS_SELECT_PROBE_, _REQ)))

# define _CCCL_CONCEPT_FRAGMENT_REQS_SELECT_PROBE_requires _CCCL_PP_PROBE_N(~, 1)
# define _CCCL_CONCEPT_FRAGMENT_REQS_SELECT_PROBE_noexcept _CCCL_PP_PROBE_N(~, 2)
# define _CCCL_CONCEPT_FRAGMENT_REQS_SELECT_PROBE_typename _CCCL_PP_PROBE_N(~, 3)
Expand All @@ -132,15 +129,14 @@ namespace __unqualified_cuda_std = _CUDA_VSTD; // NOLINT(misc-unused-alias-decls
# define _CCCL_CONCEPT_FRAGMENT_REQS_SELECT_2 _CCCL_CONCEPT_FRAGMENT_REQS_REQUIRES_OR_NOEXCEPT
# define _CCCL_CONCEPT_FRAGMENT_REQS_SELECT_3 _CCCL_CONCEPT_FRAGMENT_REQS_REQUIRES_OR_NOEXCEPT
# define _CCCL_CONCEPT_FRAGMENT_REQS_SELECT_4 _CCCL_CONCEPT_FRAGMENT_REQS_SAME_AS

# define _CCCL_CONCEPT_FRAGMENT_REQS_REQUIRES_OR_NOEXCEPT(_REQ) \
_CCCL_PP_CAT4(_CCCL_CONCEPT_FRAGMENT_REQS_REQUIRES_, _REQ)
# define _CCCL_PP_EAT_TYPENAME_PROBE_typename _CCCL_PP_PROBE(~)
# define _CCCL_PP_EAT_TYPENAME_SELECT_(_Xp, ...) \
_CCCL_PP_CAT3(_CCCL_PP_EAT_TYPENAME_SELECT_, \
_CCCL_PP_EVAL(_CCCL_PP_CHECK, _CCCL_PP_CAT3(_CCCL_PP_EAT_TYPENAME_PROBE_, _Xp)))
# define _CCCL_PP_EAT_TYPENAME_(...) \
_CCCL_PP_EVAL2(_CCCL_PP_EAT_TYPENAME_SELECT_, __VA_ARGS__, ) \
(__VA_ARGS__)
# define _CCCL_PP_EAT_TYPENAME_(...) _CCCL_PP_EVAL2(_CCCL_PP_EAT_TYPENAME_SELECT_, __VA_ARGS__, )(__VA_ARGS__)
# define _CCCL_PP_EAT_TYPENAME_SELECT_0(...) __VA_ARGS__
# define _CCCL_PP_EAT_TYPENAME_SELECT_1(...) _CCCL_PP_CAT3(_CCCL_PP_EAT_TYPENAME_, __VA_ARGS__)
# define _CCCL_PP_EAT_TYPENAME_typename
Expand Down Expand Up @@ -178,13 +174,13 @@ namespace __unqualified_cuda_std = _CUDA_VSTD; // NOLINT(misc-unused-alias-decls
# define _CCCL_CONCEPT_FRAGMENT(_NAME, ...) \
_LIBCUDACXX_HIDE_FROM_ABI auto _NAME##_CCCL_CONCEPT_FRAGMENT_impl_ _CCCL_CONCEPT_FRAGMENT_REQS_##__VA_ARGS__ > { \
} \
template <typename... _As> \
template <class... _As> \
_LIBCUDACXX_HIDE_FROM_ABI char _NAME##_CCCL_CONCEPT_FRAGMENT_( \
__cccl_concept::_Tag<_As...>*, decltype(&_NAME##_CCCL_CONCEPT_FRAGMENT_impl_<_As...>)); \
_LIBCUDACXX_HIDE_FROM_ABI char(&_NAME##_CCCL_CONCEPT_FRAGMENT_(...))[2] /**/
::__cccl_tag<_As...>*, decltype(&_NAME##_CCCL_CONCEPT_FRAGMENT_impl_<_As...>)); \
_LIBCUDACXX_HIDE_FROM_ABI char(&_NAME##_CCCL_CONCEPT_FRAGMENT_(...))[2]
# if defined(_MSC_VER) && !defined(__clang__)
# define _CCCL_CONCEPT_FRAGMENT_TRUE(...) \
__cccl_concept::__is_true<decltype(_CCCL_PP_FOR_EACH(_CCCL_CONCEPT_FRAGMENT_REQS_M, __VA_ARGS__) void())>()
::__cccl_is_true<decltype(_CCCL_PP_FOR_EACH(_CCCL_CONCEPT_FRAGMENT_REQS_M, __VA_ARGS__) void())>()
# else
# define _CCCL_CONCEPT_FRAGMENT_TRUE(...) \
!(decltype(_CCCL_PP_FOR_EACH(_CCCL_CONCEPT_FRAGMENT_REQS_M, __VA_ARGS__) void(), false){})
Expand All @@ -194,23 +190,22 @@ namespace __unqualified_cuda_std = _CUDA_VSTD; // NOLINT(misc-unused-alias-decls
# 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_REQUIRES_requires(...) __cccl_concept::__cccl_requires<__VA_ARGS__>
# define _CCCL_CONCEPT_FRAGMENT_REQS_REQUIRES_typename(...) static_cast<__cccl_concept::_Tag<__VA_ARGS__>*>(nullptr)
# 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)
// GCC < 14 can't mangle noexcept expressions, so just check that the
// expression is well-formed.
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70790
# define _CCCL_CONCEPT_FRAGMENT_REQS_REQUIRES_noexcept(...) __VA_ARGS__
# else
# define _CCCL_CONCEPT_FRAGMENT_REQS_REQUIRES_noexcept(...) __cccl_concept::__cccl_requires<noexcept(__VA_ARGS__)>
# define _CCCL_CONCEPT_FRAGMENT_REQS_REQUIRES_noexcept(...) ::__cccl_requires<noexcept(__VA_ARGS__)>
# endif
# define _CCCL_CONCEPT_FRAGMENT_REQS_SAME_AS(_REQ) \
__cccl_concept::__cccl_requires< \
_CUDA_VSTD::same_as<_CCCL_PP_CAT4(_CCCL_CONCEPT_FRAGMENT_REQS_SAME_AS_, _REQ) _CCCL_PP_RPAREN>>
::__cccl_requires<_CUDA_VSTD::same_as<_CCCL_PP_CAT4(_CCCL_CONCEPT_FRAGMENT_REQS_SAME_AS_, _REQ) _CCCL_PP_RPAREN>>
# define _CCCL_CONCEPT_FRAGMENT_REQS_SAME_AS__Same_as(...) __VA_ARGS__, decltype _CCCL_PP_LPAREN

# define _CCCL_FRAGMENT(_NAME, ...) \
(1u == sizeof(_NAME##_CCCL_CONCEPT_FRAGMENT_(static_cast<__cccl_concept::_Tag<__VA_ARGS__>*>(nullptr), nullptr)))
(1u == sizeof(_NAME##_CCCL_CONCEPT_FRAGMENT_(static_cast<::__cccl_tag<__VA_ARGS__>*>(nullptr), nullptr)))

# endif

Expand All @@ -225,7 +220,7 @@ namespace __unqualified_cuda_std = _CUDA_VSTD; // NOLINT(misc-unused-alias-decls
// );
//
// Can only be used as the last requirement in a concept definition.
# if defined(__cpp_concepts) && _CCCL_STD_VER >= 2020
# if defined(__cpp_concepts) && _CCCL_STD_VER >= 2020 || defined(_CCCL_DOXYGEN_INVOKED)
# define _CCCL_REQUIRES_EXPR(_TY, ...) requires(__VA_ARGS__) _CCCL_REQUIRES_EXPR_2
# define _CCCL_REQUIRES_EXPR_2(...) {_CCCL_PP_FOR_EACH(_CCCL_CONCEPT_FRAGMENT_REQS_M, __VA_ARGS__)}
# else
Expand All @@ -249,27 +244,29 @@ namespace __unqualified_cuda_std = _CUDA_VSTD; // NOLINT(misc-unused-alias-decls
# define _CCCL_REQUIRES_EXPR_EXPAND_TPARAMS(...) _CCCL_PP_FOR_EACH(_CCCL_REQUIRES_EXPR_EXPAND_TPARAM, __VA_ARGS__)

# define _CCCL_REQUIRES_EXPR(_TY, ...) \
__cccl_concept::__requires_expr_impl<struct _CCCL_PP_CAT( \
__cccl_requires_expr_detail_, __LINE__) _CCCL_REQUIRES_EXPR_EXPAND_TPARAMS _TY>:: \
__cccl_is_satisfied(static_cast<__cccl_concept::_Tag<void _CCCL_REQUIRES_EXPR_EXPAND_TPARAMS _TY>*>(nullptr), \
static_cast<void (*)(__VA_ARGS__)>(nullptr)); \
::__cccl_requires_expr_impl< \
struct _CCCL_PP_CAT(__cccl_requires_expr_detail_, __LINE__) _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_, __LINE__) \
{ \
using _Self_t = _CCCL_PP_CAT(__cccl_requires_expr_detail_, __LINE__); \
using __cccl_self_t = _CCCL_PP_CAT(__cccl_requires_expr_detail_, __LINE__); \
template <class _CCCL_REQUIRES_EXPR_TPARAMS _TY> \
_LIBCUDACXX_HIDE_FROM_ABI static auto _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*>(&_Self_t::_Well_formed<Args...>))> \
_LIBCUDACXX_HIDE_FROM_ABI static constexpr bool __cccl_is_satisfied(__cccl_concept::_Tag<Args...>*, Sig*) \
{ \
return true; \
} \
_LIBCUDACXX_HIDE_FROM_ABI static constexpr bool __cccl_is_satisfied(void*, ...) \
{ \
return false; \
} \
_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; \
} \
}
# endif

Expand Down

0 comments on commit 80031e2

Please sign in to comment.