Skip to content

Commit db2ced2

Browse files
committed
Unify __countr_zero_impl for C++03 and later
1 parent b4c2c81 commit db2ced2

File tree

1 file changed

+5
-52
lines changed

1 file changed

+5
-52
lines changed

libcxx/include/__bit/countr.h

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <__bit/rotate.h>
1616
#include <__concepts/arithmetic.h>
1717
#include <__config>
18-
#include <__type_traits/enable_if.h>
1918
#include <__type_traits/is_unsigned.h>
2019
#include <limits>
2120

@@ -40,74 +39,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD
4039
return __builtin_ctzll(__x);
4140
}
4241

43-
#ifndef _LIBCPP_CXX03_LANG
44-
// constexpr implementation for C++11 and later
45-
4642
// Precondition: __t != 0 (the caller __countr_zero handles __t == 0 as a special case)
4743
template <class _Tp>
48-
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr int __countr_zero_impl(_Tp __t) _NOEXCEPT {
44+
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countr_zero_impl(_Tp __t) _NOEXCEPT {
45+
_LIBCPP_ASSERT_INTERNAL(__t != 0, "__countr_zero_impl called with zero value");
4946
static_assert(is_unsigned<_Tp>::value, "__countr_zero_impl only works with unsigned types");
50-
if constexpr (sizeof(_Tp) <= sizeof(unsigned int)) {
47+
if _LIBCPP_CONSTEXPR (sizeof(_Tp) <= sizeof(unsigned int)) {
5148
return std::__libcpp_ctz(static_cast<unsigned int>(__t));
52-
} else if constexpr (sizeof(_Tp) <= sizeof(unsigned long)) {
49+
} else if _LIBCPP_CONSTEXPR (sizeof(_Tp) <= sizeof(unsigned long)) {
5350
return std::__libcpp_ctz(static_cast<unsigned long>(__t));
54-
} else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long)) {
51+
} else if _LIBCPP_CONSTEXPR (sizeof(_Tp) <= sizeof(unsigned long long)) {
5552
return std::__libcpp_ctz(static_cast<unsigned long long>(__t));
5653
} else {
57-
# if _LIBCPP_STD_VER == 11
58-
// A recursive constexpr implementation for C++11
59-
unsigned long long __ull = static_cast<unsigned long long>(__t);
60-
const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
61-
return __ull == 0ull ? __ulldigits + std::__countr_zero_impl<_Tp>(__t >> __ulldigits) : std::__libcpp_ctz(__ull);
62-
# else
6354
int __ret = 0;
6455
const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
6556
while (static_cast<unsigned long long>(__t) == 0uLL) {
6657
__ret += __ulldigits;
6758
__t >>= __ulldigits;
6859
}
6960
return __ret + std::__libcpp_ctz(static_cast<unsigned long long>(__t));
70-
# endif
71-
}
72-
}
73-
74-
#else
75-
// implementation for C++03
76-
77-
template < class _Tp, __enable_if_t<is_unsigned<_Tp>::value && sizeof(_Tp) <= sizeof(unsigned int), int> = 0>
78-
_LIBCPP_HIDE_FROM_ABI int __countr_zero_impl(_Tp __t) {
79-
return std::__libcpp_ctz(static_cast<unsigned int>(__t));
80-
}
81-
82-
template < class _Tp,
83-
__enable_if_t<is_unsigned<_Tp>::value && (sizeof(_Tp) > sizeof(unsigned int)) &&
84-
sizeof(_Tp) <= sizeof(unsigned long),
85-
int> = 0 >
86-
_LIBCPP_HIDE_FROM_ABI int __countr_zero_impl(_Tp __t) {
87-
return std::__libcpp_ctz(static_cast<unsigned long>(__t));
88-
}
89-
90-
template < class _Tp,
91-
__enable_if_t<is_unsigned<_Tp>::value && (sizeof(_Tp) > sizeof(unsigned long)) &&
92-
sizeof(_Tp) <= sizeof(unsigned long long),
93-
int> = 0 >
94-
_LIBCPP_HIDE_FROM_ABI int __countr_zero_impl(_Tp __t) {
95-
return std::__libcpp_ctz(static_cast<unsigned long long>(__t));
96-
}
97-
98-
template < class _Tp, __enable_if_t<is_unsigned<_Tp>::value && (sizeof(_Tp) > sizeof(unsigned long long)), int> = 0 >
99-
_LIBCPP_HIDE_FROM_ABI int __countr_zero_impl(_Tp __t) {
100-
int __ret = 0;
101-
const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
102-
while (static_cast<unsigned long long>(__t) == 0uLL) {
103-
__ret += __ulldigits;
104-
__t >>= __ulldigits;
10561
}
106-
return __ret + std::__libcpp_ctz(static_cast<unsigned long long>(__t));
10762
}
10863

109-
#endif // _LIBCPP_CXX03_LANG
110-
11164
template <class _Tp>
11265
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __countr_zero(_Tp __t) _NOEXCEPT {
11366
static_assert(is_unsigned<_Tp>::value, "__countr_zero only works with unsigned types");

0 commit comments

Comments
 (0)