|
20 | 20 | # pragma system_header |
21 | 21 | #endif // no system header |
22 | 22 |
|
23 | | -#include <cuda/std/__type_traits/underlying_type.h> |
| 23 | +#include <cuda/std/__bit/has_single_bit.h> |
| 24 | +#include <cuda/std/__fwd/execution_policy.h> |
24 | 25 | #include <cuda/std/cstdint> |
25 | 26 |
|
26 | 27 | #include <cuda/std/__cccl/prologue.h> |
27 | 28 |
|
28 | 29 | _CCCL_BEGIN_NAMESPACE_CUDA_STD_EXECUTION |
29 | 30 |
|
30 | | -enum class __execution_policy : uint32_t |
| 31 | +[[nodiscard]] _CCCL_API constexpr bool __has_unique_backend(const __execution_backend __backends) noexcept |
31 | 32 | { |
32 | | - __invalid_execution_policy = 0, |
33 | | - __sequenced = 1 << 0, |
34 | | - __parallel = 1 << 1, |
35 | | - __unsequenced = 1 << 2, |
36 | | - __parallel_unsequenced = __execution_policy::__parallel | __execution_policy::__unsequenced, |
37 | | -}; |
38 | | - |
39 | | -[[nodiscard]] _CCCL_API constexpr bool |
40 | | -__satisfies_execution_policy(__execution_policy __lhs, __execution_policy __rhs) noexcept |
41 | | -{ |
42 | | - return (static_cast<uint32_t>(__lhs) & static_cast<uint32_t>(__rhs)) != 0; |
| 33 | + return ::cuda::std::has_single_bit(static_cast<uint32_t>(__backends)); |
43 | 34 | } |
44 | 35 |
|
45 | | -template <__execution_policy _Policy> |
46 | | -struct __policy |
| 36 | +//! @brief Base class for our execution policies. |
| 37 | +//! It takes an untagged uint32_t because we want to be able to store 3 different enumerations in it. |
| 38 | +template <uint32_t _Policy, __execution_backend _Backend> |
| 39 | +struct __execution_policy_base |
47 | 40 | { |
48 | | - template <__execution_policy _OtherPolicy> |
49 | | - [[nodiscard]] _CCCL_API friend constexpr bool operator==(const __policy&, const __policy<_OtherPolicy>&) noexcept |
| 41 | + //! @brief Tag that identifies this and all derived classes as a CCCL execution policy |
| 42 | + static constexpr uint32_t __cccl_policy_ = _Policy; |
| 43 | + |
| 44 | + template <uint32_t _OtherPolicy, __execution_backend _OtherBackend> |
| 45 | + [[nodiscard]] _CCCL_API friend constexpr bool |
| 46 | + operator==(const __execution_policy_base&, const __execution_policy_base<_OtherPolicy, _OtherBackend>&) noexcept |
50 | 47 | { |
51 | | - using __underlying_t = underlying_type_t<__execution_policy>; |
52 | | - return (static_cast<__underlying_t>(_Policy) == static_cast<__underlying_t>(_OtherPolicy)); |
| 48 | + return _Policy == _OtherPolicy; |
53 | 49 | } |
54 | 50 |
|
55 | 51 | #if _CCCL_STD_VER <= 2017 |
56 | | - template <__execution_policy _OtherPolicy> |
57 | | - [[nodiscard]] _CCCL_API friend constexpr bool operator!=(const __policy&, const __policy<_OtherPolicy>&) noexcept |
| 52 | + template <uint32_t _OtherPolicy, __execution_backend _OtherBackend> |
| 53 | + [[nodiscard]] _CCCL_API friend constexpr bool |
| 54 | + operator!=(const __execution_policy_base&, const __execution_policy_base<_OtherPolicy, _OtherBackend>&) noexcept |
58 | 55 | { |
59 | | - using __underlying_t = underlying_type_t<__execution_policy>; |
60 | | - return (static_cast<__underlying_t>(_Policy) != static_cast<__underlying_t>(_OtherPolicy)); |
| 56 | + return _Policy != _OtherPolicy; |
61 | 57 | } |
62 | 58 | #endif // _CCCL_STD_VER <= 2017 |
63 | 59 |
|
64 | | - static constexpr __execution_policy __policy_ = _Policy; |
65 | | -}; |
| 60 | + //! @brief Extracts the execution policy from the stored _Policy |
| 61 | + [[nodiscard]] _CCCL_API static constexpr __execution_policy __get_policy() noexcept |
| 62 | + { |
| 63 | + return __policy_to_execution_policy<_Policy>; |
| 64 | + } |
66 | 65 |
|
67 | | -struct sequenced_policy : public __policy<__execution_policy::__sequenced> |
68 | | -{}; |
| 66 | + //! @brief Extracts the execution backend from the stored _Policy |
| 67 | + [[nodiscard]] _CCCL_API static constexpr __execution_backend __get_backend() noexcept |
| 68 | + { |
| 69 | + return __policy_to_execution_backend<_Policy>; |
| 70 | + } |
| 71 | +}; |
69 | 72 |
|
| 73 | +using sequenced_policy = __execution_policy_base<static_cast<uint32_t>(__execution_policy::__sequenced)>; |
70 | 74 | _CCCL_GLOBAL_CONSTANT sequenced_policy seq{}; |
71 | 75 |
|
72 | | -struct parallel_policy : public __policy<__execution_policy::__parallel> |
73 | | -{}; |
| 76 | +using parallel_policy = __execution_policy_base<static_cast<uint32_t>(__execution_policy::__parallel)>; |
74 | 77 | _CCCL_GLOBAL_CONSTANT parallel_policy par{}; |
75 | 78 |
|
76 | | -struct parallel_unsequenced_policy : public __policy<__execution_policy::__parallel_unsequenced> |
77 | | -{}; |
| 79 | +using parallel_unsequenced_policy = |
| 80 | + __execution_policy_base<static_cast<uint32_t>(__execution_policy::__parallel_unsequenced)>; |
78 | 81 | _CCCL_GLOBAL_CONSTANT parallel_unsequenced_policy par_unseq{}; |
79 | 82 |
|
80 | | -struct unsequenced_policy : public __policy<__execution_policy::__unsequenced> |
81 | | -{}; |
| 83 | +using unsequenced_policy = __execution_policy_base<static_cast<uint32_t>(__execution_policy::__unsequenced)>; |
82 | 84 | _CCCL_GLOBAL_CONSTANT unsequenced_policy unseq{}; |
83 | 85 |
|
84 | 86 | _CCCL_END_NAMESPACE_CUDA_STD_EXECUTION |
|
0 commit comments