diff --git a/.upstream-tests/test/cuda/memory_resource/memory_resource.concepts/memory_resource.pass.cpp b/.upstream-tests/test/cuda/memory_resource/memory_resource.concepts/memory_resource.pass.cpp new file mode 100644 index 0000000000..ecf3447b9c --- /dev/null +++ b/.upstream-tests/test/cuda/memory_resource/memory_resource.concepts/memory_resource.pass.cpp @@ -0,0 +1,147 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11 + +// cuda::resource, cuda::resource_with +#include + +#include + +struct invalid_argument {}; + +namespace test_resource { +struct valid_resource { + void* allocate(std::size_t, std::size_t) { return nullptr; } + void deallocate(void*, std::size_t, std::size_t) {} + bool operator==(const valid_resource&) { return true; } +}; +static_assert(cuda::resource, ""); + +struct invalid_allocate_argument { + void* allocate(invalid_argument, std::size_t) { return nullptr; } + void deallocate(void*, std::size_t, std::size_t) {} + bool operator==(const valid_resource&) { return true; } +}; +static_assert(!cuda::resource, ""); + +struct invalid_allocate_return { + int allocate(std::size_t, std::size_t) { return 42; } + void deallocate(void*, std::size_t, std::size_t) {} + bool operator==(const valid_resource&) { return true; } +}; +static_assert(!cuda::resource, ""); + +struct invalid_deallocate_argument { + void* allocate(std::size_t, std::size_t) { return nullptr; } + void deallocate(void*, invalid_argument, std::size_t) {} + bool operator==(const valid_resource&) { return true; } +}; +static_assert(!cuda::resource, ""); + +struct non_comparable { + void* allocate(std::size_t, std::size_t) { return nullptr; } + void deallocate(void*, std::size_t, std::size_t) {} +}; +// TODO: Implement equality_comparable +static_assert(cuda::resource, ""); +} // namespace test_resource + +namespace test_has_property { +struct prop_with_value { + using value_type = int; +}; +struct prop {}; + +struct valid_property { + friend void get_property(const valid_property&, prop) {} +}; +static_assert(!cuda::has_property, ""); +static_assert(cuda::has_property, ""); +static_assert(!cuda::has_property_with, ""); + +struct valid_property_with_value { + friend int get_property(const valid_property_with_value&, prop_with_value) { + return 42; + } +}; +static_assert(cuda::has_property, + ""); +static_assert(!cuda::has_property, ""); +static_assert( + cuda::has_property_with, + ""); +static_assert(!cuda::has_property_with, + ""); + +struct derived_from_property : public valid_property { + friend int get_property(const derived_from_property&, prop_with_value) { + return 42; + } +}; +static_assert(cuda::has_property, ""); +static_assert(cuda::has_property, ""); +static_assert( + cuda::has_property_with, ""); +static_assert( + !cuda::has_property_with, + ""); +} // namespace test_has_property + +namespace test_resource_with { +struct prop_with_value {}; +struct prop {}; + +struct valid_resource_with_property { + void* allocate(std::size_t, std::size_t) { return nullptr; } + void deallocate(void*, std::size_t, std::size_t) {} + bool operator==(const valid_resource_with_property&) { return true; } + friend void get_property(const valid_resource_with_property&, + prop_with_value) {} +}; +static_assert( + cuda::resource_with, ""); + +struct valid_resource_without_property { + void* allocate(std::size_t, std::size_t) { return nullptr; } + void deallocate(void*, std::size_t, std::size_t) {} + bool operator==(const valid_resource_without_property&) { return true; } +}; +static_assert( + !cuda::resource_with, ""); + +struct invalid_resource_with_property { + friend void get_property(const invalid_resource_with_property&, + prop_with_value) {} +}; +static_assert( + !cuda::resource_with, ""); + +struct resource_with_many_properties { + void* allocate(std::size_t, std::size_t) { return nullptr; } + void deallocate(void*, std::size_t, std::size_t) {} + bool operator==(const resource_with_many_properties&) { return true; } + friend void get_property(const resource_with_many_properties&, + prop_with_value) {} + friend void get_property(const resource_with_many_properties&, prop) {} +}; +static_assert( + cuda::resource_with, + ""); +static_assert(!cuda::resource_with, + ""); + +struct derived_with_property : public valid_resource_without_property { + friend void get_property(const derived_with_property&, prop_with_value) {} +}; +static_assert(cuda::resource_with, ""); +} // namespace test_resource_with + +int main(int, char**) { return 0; } diff --git a/include/cuda/memory_resource b/include/cuda/memory_resource new file mode 100644 index 0000000000..dcc816d57c --- /dev/null +++ b/include/cuda/memory_resource @@ -0,0 +1,98 @@ +//===----------------------------------------------------------------------===// +// +// Part of the CUDA Toolkit, 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _CUDA_MEMORY_RESOURCE +#define _CUDA_MEMORY_RESOURCE + +#include + +#include +#include + +#include + +#if _LIBCUDACXX_STD_VER > 11 +_LIBCUDACXX_BEGIN_NAMESPACE_CUDA + +/////////////////////////////////////////////////////////////////////////////// +// memory_resource +_LIBCUDACXX_TEMPLATE(class _Ret, class _Ptr) +(requires _CUDA_VSTD::is_same_v<_Ptr, _Ret>)void _Returns_matching(_Ptr) {} + +/// \concept _Has_member_allocate +/// \brief The \c _Has_member_allocate concept +template +_LIBCUDACXX_CONCEPT_FRAGMENT( + _Has_member_allocate_, + requires(_Resource &__res, size_t __bytes, size_t __alignment) // + (_Returns_matching(__res.allocate(__bytes, __alignment)))); +template +_LIBCUDACXX_CONCEPT _Has_member_allocate = + _LIBCUDACXX_FRAGMENT(_Has_member_allocate_, _Resource); + +/// \concept _Has_member_deallocate +/// \brief The \c _Has_member_deallocate concept +template +_LIBCUDACXX_CONCEPT_FRAGMENT(_Has_member_deallocate_, + requires(_Resource &__res, void *__ptr, + size_t __bytes, + size_t __alignment) // + (__res.deallocate(__ptr, __bytes, __alignment))); +template +_LIBCUDACXX_CONCEPT _Has_member_deallocate = + _LIBCUDACXX_FRAGMENT(_Has_member_deallocate_, _Resource); + +/// \concept resource +/// \brief The \c resource concept +template +_LIBCUDACXX_CONCEPT resource = + _Has_member_allocate<_Resource> &&_Has_member_deallocate<_Resource> + /* && _CUDA_VSTD::equality_comparable<_Resource> */; + +/// \concept has_property +/// \brief The \c has_property concept +template +_LIBCUDACXX_CONCEPT_FRAGMENT(_Has_property_, + requires(const _Resource &__res) // + (get_property(__res, _Property{}))); +template +_LIBCUDACXX_CONCEPT has_property = _LIBCUDACXX_FRAGMENT(_Has_property_, + _Resource, _Property); + +/// \concept has_property_with +/// \brief The \c has_property_with concept +template +_LIBCUDACXX_CONCEPT_FRAGMENT( + _Has_property_with_, + requires(const _Resource &__res) // + (_Returns_matching<_Return>(get_property(__res, _Property{})), + _Returns_matching<_Return>( + _CUDA_VSTD::declval()))); +template +_LIBCUDACXX_CONCEPT has_property_with = + _LIBCUDACXX_FRAGMENT(_Has_property_with_, _Resource, _Property, _Return); + +/// \concept resource +/// \brief The \c resource concept +template +#if _LIBCUDACXX_STD_VER < 17 +_LIBCUDACXX_CONCEPT resource_with = + resource<_Resource> &&_CUDA_VSTD::conjunction<_CUDA_VSTD::bool_constant< + has_property<_Resource, _Properties>>...>::value; +#else +_LIBCUDACXX_CONCEPT resource_with = resource<_Resource> // + && (has_property<_Resource, _Properties> && + ...); +#endif + +_LIBCUDACXX_END_NAMESPACE_CUDA +#endif // _LIBCUDACXX_STD_VER > 11 + +#include + +#endif //_LIBCUDACXX_BEGIN_NAMESPACE_CUDA \ No newline at end of file diff --git a/include/cuda/std/detail/__concepts b/include/cuda/std/detail/__concepts new file mode 100644 index 0000000000..0e3dac000e --- /dev/null +++ b/include/cuda/std/detail/__concepts @@ -0,0 +1,282 @@ +//===----------------------------------------------------------------------===// +// +// Part of libcu++, the C++ Standard Library for your entire system, +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _CUDA___CONCEPTS +#define _CUDA___CONCEPTS + +#include "__config" + +#if _LIBCUDACXX_STD_VER > 11 + +#include + +#define _LIBCUDACXX_PP_CAT_(X, ...) X##__VA_ARGS__ +#define _LIBCUDACXX_PP_CAT(X, ...) _LIBCUDACXX_PP_CAT_(X, __VA_ARGS__) + +#define _LIBCUDACXX_PP_CAT2_(X, ...) X##__VA_ARGS__ +#define _LIBCUDACXX_PP_CAT2(X, ...) _LIBCUDACXX_PP_CAT2_(X, __VA_ARGS__) + +#define _LIBCUDACXX_PP_CAT3_(X, ...) X##__VA_ARGS__ +#define _LIBCUDACXX_PP_CAT3(X, ...) _LIBCUDACXX_PP_CAT3_(X, __VA_ARGS__) + +#define _LIBCUDACXX_PP_CAT4_(X, ...) X##__VA_ARGS__ +#define _LIBCUDACXX_PP_CAT4(X, ...) _LIBCUDACXX_PP_CAT4_(X, __VA_ARGS__) + +#define _LIBCUDACXX_PP_EVAL_(X, ARGS) X ARGS +#define _LIBCUDACXX_PP_EVAL(X, ...) _LIBCUDACXX_PP_EVAL_(X, (__VA_ARGS__)) + +#define _LIBCUDACXX_PP_EVAL2_(X, ARGS) X ARGS +#define _LIBCUDACXX_PP_EVAL2(X, ...) _LIBCUDACXX_PP_EVAL2_(X, (__VA_ARGS__)) + +#define _LIBCUDACXX_PP_EXPAND(...) __VA_ARGS__ +#define _LIBCUDACXX_PP_EAT(...) + +#define _LIBCUDACXX_PP_CHECK(...) \ + _LIBCUDACXX_PP_EXPAND(_LIBCUDACXX_PP_CHECK_N(__VA_ARGS__, 0, )) +#define _LIBCUDACXX_PP_CHECK_N(x, n, ...) n +#define _LIBCUDACXX_PP_PROBE(x) x, 1, +#define _LIBCUDACXX_PP_PROBE_N(x, n) x, n, + +#define _LIBCUDACXX_PP_IS_PAREN(x) \ + _LIBCUDACXX_PP_CHECK(_LIBCUDACXX_PP_IS_PAREN_PROBE x) +#define _LIBCUDACXX_PP_IS_PAREN_PROBE(...) _LIBCUDACXX_PP_PROBE(~) + +// The final _LIBCUDACXX_PP_EXPAND here is to avoid +// https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly +#define _LIBCUDACXX_PP_COUNT(...) \ + _LIBCUDACXX_PP_EXPAND(_LIBCUDACXX_PP_COUNT_( \ + __VA_ARGS__, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, \ + 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, \ + 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, )) \ + /**/ +#define _LIBCUDACXX_PP_COUNT_( \ + _01, _02, _03, _04, _05, _06, _07, _08, _09, _10, _11, _12, _13, _14, _15, \ + _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, \ + _46, _47, _48, _49, _50, N, ...) \ + N /**/ + +#define _LIBCUDACXX_PP_IIF(BIT) _LIBCUDACXX_PP_CAT_(_LIBCUDACXX_PP_IIF_, BIT) +#define _LIBCUDACXX_PP_IIF_0(TRUE, ...) __VA_ARGS__ +#define _LIBCUDACXX_PP_IIF_1(TRUE, ...) TRUE + +#define _LIBCUDACXX_PP_LPAREN ( + +#define _LIBCUDACXX_PP_NOT(BIT) _LIBCUDACXX_PP_CAT_(_LIBCUDACXX_PP_NOT_, BIT) +#define _LIBCUDACXX_PP_NOT_0 1 +#define _LIBCUDACXX_PP_NOT_1 0 + +#define _LIBCUDACXX_PP_EMPTY() +#define _LIBCUDACXX_PP_COMMA() , +#define _LIBCUDACXX_PP_LBRACE() { +#define _LIBCUDACXX_PP_RBRACE() } +#define _LIBCUDACXX_PP_COMMA_IIF(X) \ + _LIBCUDACXX_PP_IIF(X)(_LIBCUDACXX_PP_EMPTY, _LIBCUDACXX_PP_COMMA)() /**/ + +#define _LIBCUDACXX_PP_FOR_EACH(M, ...) \ + _LIBCUDACXX_PP_FOR_EACH_N(_LIBCUDACXX_PP_COUNT(__VA_ARGS__), M, __VA_ARGS__) +#define _LIBCUDACXX_PP_FOR_EACH_N(N, M, ...) \ + _LIBCUDACXX_PP_CAT2(_LIBCUDACXX_PP_FOR_EACH_, N)(M, __VA_ARGS__) +#define _LIBCUDACXX_PP_FOR_EACH_1(M, _1) M(_1) +#define _LIBCUDACXX_PP_FOR_EACH_2(M, _1, _2) M(_1) M(_2) +#define _LIBCUDACXX_PP_FOR_EACH_3(M, _1, _2, _3) M(_1) M(_2) M(_3) +#define _LIBCUDACXX_PP_FOR_EACH_4(M, _1, _2, _3, _4) M(_1) M(_2) M(_3) M(_4) +#define _LIBCUDACXX_PP_FOR_EACH_5(M, _1, _2, _3, _4, _5) \ + M(_1) M(_2) M(_3) M(_4) M(_5) +#define _LIBCUDACXX_PP_FOR_EACH_6(M, _1, _2, _3, _4, _5, _6) \ + M(_1) M(_2) M(_3) M(_4) M(_5) M(_6) +#define _LIBCUDACXX_PP_FOR_EACH_7(M, _1, _2, _3, _4, _5, _6, _7) \ + M(_1) M(_2) M(_3) M(_4) M(_5) M(_6) M(_7) +#define _LIBCUDACXX_PP_FOR_EACH_8(M, _1, _2, _3, _4, _5, _6, _7, _8) \ + M(_1) M(_2) M(_3) M(_4) M(_5) M(_6) M(_7) M(_8) + +#define _LIBCUDACXX_PP_PROBE_EMPTY_PROBE__LIBCUDACXX_PP_PROBE_EMPTY \ + _LIBCUDACXX_PP_PROBE(~) + +#define _LIBCUDACXX_PP_PROBE_EMPTY() +#define _LIBCUDACXX_PP_IS_NOT_EMPTY(...) \ + _LIBCUDACXX_PP_EVAL( \ + _LIBCUDACXX_PP_CHECK, \ + _LIBCUDACXX_PP_CAT(_LIBCUDACXX_PP_PROBE_EMPTY_PROBE_, \ + _LIBCUDACXX_PP_PROBE_EMPTY __VA_ARGS__())) \ + /**/ + +#define _LIBCUDACXX_PP_TAIL(_, ...) __VA_ARGS__ + +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_M0(REQ) \ + _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_(REQ)(REQ) +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_M1(REQ) _LIBCUDACXX_PP_EXPAND REQ +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_(...) \ + { _LIBCUDACXX_PP_FOR_EACH(_LIBCUDACXX_CONCEPT_FRAGMENT_REQS_M, __VA_ARGS__) } +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_(REQ) \ + _LIBCUDACXX_PP_CAT3( \ + _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_, \ + _LIBCUDACXX_PP_EVAL( \ + _LIBCUDACXX_PP_CHECK, \ + _LIBCUDACXX_PP_CAT3(_LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_PROBE_, \ + REQ))) \ + /**/ +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_PROBE_requires \ + _LIBCUDACXX_PP_PROBE_N(~, 1) +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_PROBE_noexcept \ + _LIBCUDACXX_PP_PROBE_N(~, 2) +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_PROBE_typename \ + _LIBCUDACXX_PP_PROBE_N(~, 3) + +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_0 _LIBCUDACXX_PP_EXPAND +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_1 \ + _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_OR_NOEXCEPT +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_2 \ + _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_OR_NOEXCEPT +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_SELECT_3 \ + _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_OR_NOEXCEPT +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_OR_NOEXCEPT(REQ) \ + _LIBCUDACXX_PP_CAT4(_LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_, REQ) +#define _LIBCUDACXX_PP_EAT_TYPENAME_PROBE_typename _LIBCUDACXX_PP_PROBE(~) +#define _LIBCUDACXX_PP_EAT_TYPENAME_SELECT_(X, ...) \ + _LIBCUDACXX_PP_CAT3( \ + _LIBCUDACXX_PP_EAT_TYPENAME_SELECT_, \ + _LIBCUDACXX_PP_EVAL( \ + _LIBCUDACXX_PP_CHECK, \ + _LIBCUDACXX_PP_CAT3(_LIBCUDACXX_PP_EAT_TYPENAME_PROBE_, X))) +#define _LIBCUDACXX_PP_EAT_TYPENAME_(...) \ + _LIBCUDACXX_PP_EVAL2(_LIBCUDACXX_PP_EAT_TYPENAME_SELECT_, __VA_ARGS__, ) \ + (__VA_ARGS__) +#define _LIBCUDACXX_PP_EAT_TYPENAME_SELECT_0(...) __VA_ARGS__ +#define _LIBCUDACXX_PP_EAT_TYPENAME_SELECT_1(...) \ + _LIBCUDACXX_PP_CAT3(_LIBCUDACXX_PP_EAT_TYPENAME_, __VA_ARGS__) +#define _LIBCUDACXX_PP_EAT_TYPENAME_typename + +#if _LIBCUDACXX_CXX_CONCEPTS || defined(_LIBCUDACXX_DOXYGEN_INVOKED) + +#define _LIBCUDACXX_CONCEPT concept + +#define _LIBCUDACXX_CONCEPT_FRAGMENT(NAME, ...) \ + concept NAME = \ + _LIBCUDACXX_PP_CAT(_LIBCUDACXX_CONCEPT_FRAGMENT_REQS_, __VA_ARGS__) +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_requires(...) \ + requires(__VA_ARGS__) _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_ +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_M(REQ) \ + _LIBCUDACXX_PP_CAT2(_LIBCUDACXX_CONCEPT_FRAGMENT_REQS_M, \ + _LIBCUDACXX_PP_IS_PAREN(REQ)) \ + (REQ); +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_requires(...) \ + requires __VA_ARGS__ +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_typename(...) \ + typename _LIBCUDACXX_PP_EAT_TYPENAME_(__VA_ARGS__) +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_noexcept(...) \ + { __VA_ARGS__ } \ + noexcept + +#define _LIBCUDACXX_FRAGMENT(NAME, ...) NAME<__VA_ARGS__> + +#else + +#define _LIBCUDACXX_CONCEPT _LIBCUDACXX_INLINE_VAR constexpr bool + +#define _LIBCUDACXX_CONCEPT_FRAGMENT(NAME, ...) \ + auto NAME##_LIBCUDACXX_CONCEPT_FRAGMENT_impl_ \ + _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_##__VA_ARGS__ > {} \ + template \ + char NAME##_LIBCUDACXX_CONCEPT_FRAGMENT_( \ + _CUDA_VSTD::_Concept::tag *, \ + decltype(&NAME##_LIBCUDACXX_CONCEPT_FRAGMENT_impl_)); \ + char(&NAME##_LIBCUDACXX_CONCEPT_FRAGMENT_(...))[2] /**/ +#if defined(_MSC_VER) && !defined(__clang__) +#define _LIBCUDACXX_CONCEPT_FRAGMENT_TRUE(...) \ + _CUDA_VSTD::_Concept::true_() +#else +#define _LIBCUDACXX_CONCEPT_FRAGMENT_TRUE(...) \ + !(decltype(_LIBCUDACXX_PP_FOR_EACH(_LIBCUDACXX_CONCEPT_FRAGMENT_REQS_M, \ + __VA_ARGS__) void(), \ + false){}) +#endif +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_requires(...) \ + (__VA_ARGS__)->_CUDA_VSTD::enable_if_t < _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_2_ +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_2_(...) \ + _LIBCUDACXX_CONCEPT_FRAGMENT_TRUE(__VA_ARGS__) +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_M(REQ) \ + _LIBCUDACXX_PP_CAT2(_LIBCUDACXX_CONCEPT_FRAGMENT_REQS_M, \ + _LIBCUDACXX_PP_IS_PAREN(REQ)) \ + (REQ), +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_requires(...) \ + _CUDA_VSTD::requires_<__VA_ARGS__> +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_typename(...) \ + static_cast<_CUDA_VSTD::_Concept::tag<__VA_ARGS__> *>(nullptr) +#if defined(__GNUC__) && !defined(__clang__) +// GCC 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 _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_noexcept(...) __VA_ARGS__ +#else +#define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_noexcept(...) \ + _CUDA_VSTD::requires_ +#endif + +#define _LIBCUDACXX_FRAGMENT(NAME, ...) \ + (1u == sizeof(NAME##_LIBCUDACXX_CONCEPT_FRAGMENT_( \ + static_cast<_CUDA_VSTD::_Concept::tag<__VA_ARGS__> *>(nullptr), \ + nullptr))) + +#endif + +//////////////////////////////////////////////////////////////////////////////// +// _LIBCUDACXX_TEMPLATE +// Usage: +// _LIBCUDACXX_TEMPLATE(typename A, typename B) +// (requires Concept1 _LIBCUDACXX_AND Concept2) +// void foo(A a, B b) +// {} +#if _LIBCUDACXX_CXX_CONCEPTS +#define _LIBCUDACXX_TEMPLATE(...) \ + template <__VA_ARGS__> _LIBCUDACXX_PP_EXPAND /**/ +#define _LIBCUDACXX_AND && /**/ +#else +#define _LIBCUDACXX_TEMPLATE(...) \ + template <__VA_ARGS__ _LIBCUDACXX_TEMPLATE_SFINAE_AUX_ /**/ +#define _LIBCUDACXX_AND \ + &&_LIBCUDACXX_true_, int > = 0, _CUDA_VSTD::enable_if_t < /**/ +#endif + +#define _LIBCUDACXX_TEMPLATE_SFINAE(...) \ + template <__VA_ARGS__ _LIBCUDACXX_TEMPLATE_SFINAE_AUX_ /**/ +#define _LIBCUDACXX_TEMPLATE_SFINAE_AUX_(...) \ + , bool _LIBCUDACXX_true_ = true, \ + _CUDA_VSTD::enable_if_t < \ + _LIBCUDACXX_PP_CAT(_LIBCUDACXX_TEMPLATE_SFINAE_AUX_3_, \ + __VA_ARGS__) && \ + _LIBCUDACXX_true_, \ + int > = 0 > /**/ +#define _LIBCUDACXX_TEMPLATE_SFINAE_AUX_3_requires + +_LIBCUDACXX_BEGIN_NAMESPACE_STD +namespace _Concept { +template struct tag; +template inline constexpr bool true_() { return true; } +} // namespace _Concept + +#if defined(__clang__) || defined(_MSC_VER) +template _CUDA_VSTD::enable_if_t requires_() {} +#else +template +_LIBCUDACXX_INLINE_VAR constexpr _CUDA_VSTD::enable_if_t requires_ = 0; +#endif + +template +#if _LIBCUDACXX_STD_VER < 17 +_LIBCUDACXX_CONCEPT _One_of = + _CUDA_VSTD::disjunction<_CUDA_VSTD::is_same<_Ty, _Others>...>::value; +#else +_LIBCUDACXX_CONCEPT _One_of = (_CUDA_VSTD::is_same_v<_Ty, _Others> || ...); +#endif +_LIBCUDACXX_END_NAMESPACE_STD +#endif // _LIBCUDACXX_STD_VER > 11 + +#endif //_CUDA___CONCEPTS diff --git a/include/cuda/std/detail/libcxx/include/module.modulemap b/include/cuda/std/detail/libcxx/include/module.modulemap index 31d39ddf7c..fba1e8dc6c 100644 --- a/include/cuda/std/detail/libcxx/include/module.modulemap +++ b/include/cuda/std/detail/libcxx/include/module.modulemap @@ -356,6 +356,10 @@ module std [system] { header "memory" export * } + module memory_resource { + header "memory_resource" + export * + } module mutex { header "mutex" export *