13
13
#define _LIBCPP___BIT_COUNTR_H
14
14
15
15
#include < __assert>
16
- #include < __bit/rotate.h>
17
16
#include < __concepts/arithmetic.h>
18
17
#include < __config>
19
18
#include < __type_traits/is_unsigned.h>
@@ -28,55 +27,10 @@ _LIBCPP_PUSH_MACROS
28
27
29
28
_LIBCPP_BEGIN_NAMESPACE_STD
30
29
31
- [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz (unsigned __x) _NOEXCEPT {
32
- return __builtin_ctz (__x);
33
- }
34
-
35
- [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz (unsigned long __x) _NOEXCEPT {
36
- return __builtin_ctzl (__x);
37
- }
38
-
39
- [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz (unsigned long long __x) _NOEXCEPT {
40
- return __builtin_ctzll (__x);
41
- }
42
-
43
- // A constexpr implementation for C++11 and later (using clang extensions for constexpr support)
44
- // Precondition: __t != 0 (the caller __countr_zero handles __t == 0 as a special case)
45
- template <class _Tp >
46
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __countr_zero_impl (_Tp __t ) _NOEXCEPT {
47
- _LIBCPP_ASSERT_INTERNAL (__t != 0 , " __countr_zero_impl called with zero value" );
48
- static_assert (is_unsigned<_Tp>::value, " __countr_zero_impl only works with unsigned types" );
49
- if _LIBCPP_CONSTEXPR (sizeof (_Tp) <= sizeof (unsigned int )) {
50
- return std::__libcpp_ctz (static_cast <unsigned int >(__t ));
51
- } else if _LIBCPP_CONSTEXPR (sizeof (_Tp) <= sizeof (unsigned long )) {
52
- return std::__libcpp_ctz (static_cast <unsigned long >(__t ));
53
- } else if _LIBCPP_CONSTEXPR (sizeof (_Tp) <= sizeof (unsigned long long )) {
54
- return std::__libcpp_ctz (static_cast <unsigned long long >(__t ));
55
- } else {
56
- #if _LIBCPP_STD_VER == 11
57
- unsigned long long __ull = static_cast <unsigned long long >(__t );
58
- const unsigned int __ulldigits = numeric_limits<unsigned long long >::digits;
59
- return __ull == 0ull ? __ulldigits + std::__countr_zero_impl<_Tp>(__t >> __ulldigits) : std::__libcpp_ctz (__ull);
60
- #else
61
- int __ret = 0 ;
62
- const unsigned int __ulldigits = numeric_limits<unsigned long long >::digits;
63
- while (static_cast <unsigned long long >(__t ) == 0uLL) {
64
- __ret += __ulldigits;
65
- __t >>= __ulldigits;
66
- }
67
- return __ret + std::__libcpp_ctz (static_cast <unsigned long long >(__t ));
68
- #endif
69
- }
70
- }
71
-
72
30
template <class _Tp >
73
31
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __countr_zero (_Tp __t ) _NOEXCEPT {
74
32
static_assert (is_unsigned<_Tp>::value, " __countr_zero only works with unsigned types" );
75
- #if __has_builtin(__builtin_ctzg) // TODO (LLVM 21): This can be dropped once we only support Clang >= 19.
76
33
return __builtin_ctzg (__t , numeric_limits<_Tp>::digits);
77
- #else
78
- return __t != 0 ? std::__countr_zero_impl (__t ) : numeric_limits<_Tp>::digits;
79
- #endif
80
34
}
81
35
82
36
#if _LIBCPP_STD_VER >= 20
0 commit comments