14
14
#include < alpaka/intrinsic/Traits.hpp>
15
15
16
16
#include < bitset>
17
+ #include < climits>
17
18
#if __has_include(<bit>)
18
19
# include < bit>
19
20
#endif
@@ -34,71 +35,49 @@ namespace alpaka
34
35
template <>
35
36
struct Popcount <IntrinsicCpu>
36
37
{
37
- static auto popcount (IntrinsicCpu const & /* intrinsic*/ , std::uint32_t value) -> std::int32_t
38
+ template <typename UnsignedIntegral>
39
+ static auto popcount (IntrinsicCpu const & /* intrinsic*/ , UnsignedIntegral value) -> std::int32_t
38
40
{
39
41
#ifdef __cpp_lib_bitops
40
42
return std::popcount (value);
41
43
#elif BOOST_COMP_GNUC || BOOST_COMP_CLANG
42
- return __builtin_popcount (value);
43
- #elif BOOST_COMP_MSVC
44
- return __popcnt (value);
45
- #else
46
- // Fallback to standard library
47
- return static_cast <std::int32_t >(std::bitset<32 >(value).count ());
48
- #endif
49
- }
50
-
51
- static auto popcount (IntrinsicCpu const & /* intrinsic*/ , std::uint64_t value) -> std::int32_t
52
- {
53
- #ifdef __cpp_lib_bitops
54
- return std::popcount (value);
55
- #elif BOOST_COMP_GNUC || BOOST_COMP_CLANG
56
- return __builtin_popcountll (value);
44
+ if constexpr (sizeof (UnsignedIntegral) == 8 )
45
+ return __builtin_popcountll (value);
46
+ else
47
+ return __builtin_popcount (value);
57
48
#elif BOOST_COMP_MSVC
58
- return static_cast <std::int32_t >(__popcnt64 (value));
49
+ if constexpr (sizeof (UnsignedIntegral) == 8 )
50
+ return static_cast <std::int32_t >(__popcnt64 (value));
51
+ else
52
+ return __popcnt (value);
59
53
#else
60
54
// Fallback to standard library
61
- return static_cast <std::int32_t >(std::bitset<64 >(value).count ());
55
+ return static_cast <std::int32_t >(std::bitset<sizeof (UnsignedIntegral) * CHAR_BIT >(value).count ());
62
56
#endif
63
57
}
64
58
};
65
59
66
60
template <>
67
61
struct Ffs <IntrinsicCpu>
68
62
{
69
- static auto ffs (IntrinsicCpu const & /* intrinsic*/ , std::int32_t value) -> std::int32_t
63
+ template <typename Integral>
64
+ static auto ffs (IntrinsicCpu const & /* intrinsic*/ , Integral value) -> std::int32_t
70
65
{
71
66
#ifdef __cpp_lib_bitops
72
- return std::countr_zero (value);
67
+ return value == 0 ? 0 : std::countr_zero (static_cast <std:: make_unsigned_t <Integral>>( value)) + 1 ;
73
68
#elif BOOST_COMP_GNUC || BOOST_COMP_CLANG
74
- return __builtin_ffs (value);
75
- #elif BOOST_COMP_MSVC
76
- // Implementation based on
77
- // https://gitlab.freedesktop.org/cairo/cairo/commit/f5167dc2e1a13d8c4e5d66d7178a24b9b5e7ac7a
78
- unsigned long index = 0u ;
79
- if (_BitScanForward (&index , value) != 0 )
80
- return static_cast <std::int32_t >(index + 1u );
69
+ if constexpr (sizeof (Integral) == 8 )
70
+ return __builtin_ffsll (value);
81
71
else
82
- return 0 ;
83
- #else
84
- return alpaka::detail::ffsFallback (value);
85
- #endif
86
- }
87
-
88
- static auto ffs (IntrinsicCpu const & /* intrinsic*/ , std::int64_t value) -> std::int32_t
89
- {
90
- #ifdef __cpp_lib_bitops
91
- return std::countr_zero (value);
92
- #elif BOOST_COMP_GNUC || BOOST_COMP_CLANG
93
- return __builtin_ffsll (value);
72
+ return __builtin_ffs (value);
94
73
#elif BOOST_COMP_MSVC
95
74
// Implementation based on
96
75
// https://gitlab.freedesktop.org/cairo/cairo/commit/f5167dc2e1a13d8c4e5d66d7178a24b9b5e7ac7a
97
76
unsigned long index = 0u ;
98
- if ( _BitScanForward64 (& index , value) != 0 )
99
- return static_cast <std::int32_t >(index + 1u );
77
+ if constexpr ( sizeof (Integral) == 8 )
78
+ return _BitScanForward64 (& index , value) == 0 ? 0 : static_cast <std::int32_t >(index + 1u );
100
79
else
101
- return 0 ;
80
+ return _BitScanForward (& index , value) == 0 ? 0 : static_cast <std:: int32_t >( index + 1u ) ;
102
81
#else
103
82
return alpaka::detail::ffsFallback (value);
104
83
#endif
0 commit comments