//===----------------------------------------------------------------------===// // // Copyright (c) Facebook, Inc. and its affiliates. // Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // 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 // SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// #ifndef _CUDA___CONCEPTS #define _CUDA___CONCEPTS #include #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) # pragma GCC system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG) # pragma clang system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC) # pragma system_header #endif // no system header #if _CCCL_STD_VER > 2011 # define _LIBCUDACXX_PP_CAT_(_Xp, ...) _Xp##__VA_ARGS__ # define _LIBCUDACXX_PP_CAT(_Xp, ...) _LIBCUDACXX_PP_CAT_(_Xp, __VA_ARGS__) # define _LIBCUDACXX_PP_CAT2_(_Xp, ...) _Xp##__VA_ARGS__ # define _LIBCUDACXX_PP_CAT2(_Xp, ...) _LIBCUDACXX_PP_CAT2_(_Xp, __VA_ARGS__) # define _LIBCUDACXX_PP_CAT3_(_Xp, ...) _Xp##__VA_ARGS__ # define _LIBCUDACXX_PP_CAT3(_Xp, ...) _LIBCUDACXX_PP_CAT3_(_Xp, __VA_ARGS__) # define _LIBCUDACXX_PP_CAT4_(_Xp, ...) _Xp##__VA_ARGS__ # define _LIBCUDACXX_PP_CAT4(_Xp, ...) _LIBCUDACXX_PP_CAT4_(_Xp, __VA_ARGS__) # define _LIBCUDACXX_PP_EVAL_(_Xp, _ARGS) _Xp _ARGS # define _LIBCUDACXX_PP_EVAL(_Xp, ...) _LIBCUDACXX_PP_EVAL_(_Xp, (__VA_ARGS__)) # define _LIBCUDACXX_PP_EVAL2_(_Xp, _ARGS) _Xp _ARGS # define _LIBCUDACXX_PP_EVAL2(_Xp, ...) _LIBCUDACXX_PP_EVAL2_(_Xp, (__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(_Xp, _Num, ...) _Num # define _LIBCUDACXX_PP_PROBE(_Xp) _Xp, 1, # define _LIBCUDACXX_PP_PROBE_N(_Xp, _Num) _Xp, _Num, # define _LIBCUDACXX_PP_IS_PAREN(_Xp) _LIBCUDACXX_PP_CHECK(_LIBCUDACXX_PP_IS_PAREN_PROBE _Xp) # 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, \ _Np, \ ...) \ _Np /**/ # 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(_Xp) _LIBCUDACXX_PP_IIF(_Xp)(_LIBCUDACXX_PP_EMPTY, _LIBCUDACXX_PP_COMMA)() /**/ # define _LIBCUDACXX_PP_FOR_EACH(_Mp, ...) \ _LIBCUDACXX_PP_FOR_EACH_N(_LIBCUDACXX_PP_COUNT(__VA_ARGS__), _Mp, __VA_ARGS__) # define _LIBCUDACXX_PP_FOR_EACH_N(_Np, _Mp, ...) _LIBCUDACXX_PP_CAT2(_LIBCUDACXX_PP_FOR_EACH_, _Np)(_Mp, __VA_ARGS__) # define _LIBCUDACXX_PP_FOR_EACH_1(_Mp, _1) _Mp(_1) # define _LIBCUDACXX_PP_FOR_EACH_2(_Mp, _1, _2) _Mp(_1) _Mp(_2) # define _LIBCUDACXX_PP_FOR_EACH_3(_Mp, _1, _2, _3) _Mp(_1) _Mp(_2) _Mp(_3) # define _LIBCUDACXX_PP_FOR_EACH_4(_Mp, _1, _2, _3, _4) _Mp(_1) _Mp(_2) _Mp(_3) _Mp(_4) # define _LIBCUDACXX_PP_FOR_EACH_5(_Mp, _1, _2, _3, _4, _5) _Mp(_1) _Mp(_2) _Mp(_3) _Mp(_4) _Mp(_5) # define _LIBCUDACXX_PP_FOR_EACH_6(_Mp, _1, _2, _3, _4, _5, _6) _Mp(_1) _Mp(_2) _Mp(_3) _Mp(_4) _Mp(_5) _Mp(_6) # define _LIBCUDACXX_PP_FOR_EACH_7(_Mp, _1, _2, _3, _4, _5, _6, _7) \ _Mp(_1) _Mp(_2) _Mp(_3) _Mp(_4) _Mp(_5) _Mp(_6) _Mp(_7) # define _LIBCUDACXX_PP_FOR_EACH_8(_Mp, _1, _2, _3, _4, _5, _6, _7, _8) \ _Mp(_1) _Mp(_2) _Mp(_3) _Mp(_4) _Mp(_5) _Mp(_6) _Mp(_7) _Mp(_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_(_Xp, ...) \ _LIBCUDACXX_PP_CAT3( \ _LIBCUDACXX_PP_EAT_TYPENAME_SELECT_, \ _LIBCUDACXX_PP_EVAL(_LIBCUDACXX_PP_CHECK, _LIBCUDACXX_PP_CAT3(_LIBCUDACXX_PP_EAT_TYPENAME_PROBE_, _Xp))) # 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 (defined(__cpp_concepts) && _CCCL_STD_VER >= 2020) || 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, ...) \ _LIBCUDACXX_INLINE_VISIBILITY auto _NAME##_LIBCUDACXX_CONCEPT_FRAGMENT_impl_ \ _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_##__VA_ARGS__ \ > \ {} \ template \ _LIBCUDACXX_INLINE_VISIBILITY char _NAME##_LIBCUDACXX_CONCEPT_FRAGMENT_( \ _Concept::_Tag<_As...>*, decltype(&_NAME##_LIBCUDACXX_CONCEPT_FRAGMENT_impl_<_As...>)); \ _LIBCUDACXX_INLINE_VISIBILITY char(&_NAME##_LIBCUDACXX_CONCEPT_FRAGMENT_(...))[2] /**/ # if defined(_MSC_VER) && !defined(__clang__) # define _LIBCUDACXX_CONCEPT_FRAGMENT_TRUE(...) \ _Concept::_Is_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__)->_Concept::_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(...) _Concept::_Requires<__VA_ARGS__> # define _LIBCUDACXX_CONCEPT_FRAGMENT_REQS_REQUIRES_typename(...) static_cast<_Concept::_Tag<__VA_ARGS__>*>(nullptr) # if defined(_CCCL_COMPILER_GCC) // 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(...) _Concept::_Requires # endif # define _LIBCUDACXX_FRAGMENT(_NAME, ...) \ (1u == sizeof(_NAME##_LIBCUDACXX_CONCEPT_FRAGMENT_(static_cast<_Concept::_Tag<__VA_ARGS__>*>(nullptr), nullptr))) # endif //////////////////////////////////////////////////////////////////////////////// // _LIBCUDACXX_TEMPLATE // Usage: // _LIBCUDACXX_TEMPLATE(typename A, typename _Bp) // _LIBCUDACXX_REQUIRES( Concept1 _LIBCUDACXX_AND Concept2<_Bp>) // void foo(A a, _Bp b) // {} # if (defined(__cpp_concepts) && _CCCL_STD_VER >= 2020) # define _LIBCUDACXX_TEMPLATE(...) template <__VA_ARGS__> # define _LIBCUDACXX_REQUIRES(...) requires __VA_ARGS__ # define _LIBCUDACXX_AND && # define _LIBCUDACXX_TRAILING_REQUIRES(...) \ ->__VA_ARGS__ \ requires _LIBCUDACXX_PP_EXPAND # else # define _LIBCUDACXX_TEMPLATE(...) template <__VA_ARGS__ # define _LIBCUDACXX_REQUIRES(...) \ , bool _LIBCUDACXX_true_ = true, _Concept::_Enable_if_t < __VA_ARGS__ && _LIBCUDACXX_true_, int > = 0 > /**/ # define _LIBCUDACXX_AND &&_LIBCUDACXX_true_, int > = 0, _Concept::_Enable_if_t < # define _LIBCUDACXX_TRAILING_REQUIRES_AUX_(...) , __VA_ARGS__ > # define _LIBCUDACXX_TRAILING_REQUIRES(...) ->_Concept::_Requires_t < __VA_ARGS__ _LIBCUDACXX_TRAILING_REQUIRES_AUX_ # endif namespace _Concept { template struct _Select {}; template <> struct _Select { template using type = _Tp; }; template using _Enable_if_t = typename _Select<_Bp>::template type<_Tp>; template using _Requires_t = typename _Select<_Bp>::template type<_Tp>; template struct _Tag; template _LIBCUDACXX_INLINE_VISIBILITY inline constexpr bool _Is_true() { return true; } # if defined(_CCCL_COMPILER_CLANG) || defined(_CCCL_COMPILER_MSVC) template _LIBCUDACXX_INLINE_VISIBILITY _Concept::_Enable_if_t<_Bp> _Requires() {} # else template = 0> _LIBCUDACXX_INLINE_VAR constexpr int _Requires = 0; # endif } // namespace _Concept #endif // _CCCL_STD_VER > 2011 #endif //_CUDA___CONCEPTS