15
15
#include < __bit/rotate.h>
16
16
#include < __concepts/arithmetic.h>
17
17
#include < __config>
18
- #include < __type_traits/enable_if.h>
19
18
#include < __type_traits/is_unsigned.h>
20
19
#include < limits>
21
20
@@ -40,74 +39,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD
40
39
return __builtin_ctzll (__x);
41
40
}
42
41
43
- #ifndef _LIBCPP_CXX03_LANG
44
- // constexpr implementation for C++11 and later
45
-
46
42
// Precondition: __t != 0 (the caller __countr_zero handles __t == 0 as a special case)
47
43
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" );
49
46
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 )) {
51
48
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 )) {
53
50
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 )) {
55
52
return std::__libcpp_ctz (static_cast <unsigned long long >(__t ));
56
53
} 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
63
54
int __ret = 0 ;
64
55
const unsigned int __ulldigits = numeric_limits<unsigned long long >::digits;
65
56
while (static_cast <unsigned long long >(__t ) == 0uLL) {
66
57
__ret += __ulldigits;
67
58
__t >>= __ulldigits;
68
59
}
69
60
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;
105
61
}
106
- return __ret + std::__libcpp_ctz (static_cast <unsigned long long >(__t ));
107
62
}
108
63
109
- #endif // _LIBCPP_CXX03_LANG
110
-
111
64
template <class _Tp >
112
65
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __countr_zero (_Tp __t ) _NOEXCEPT {
113
66
static_assert (is_unsigned<_Tp>::value, " __countr_zero only works with unsigned types" );
0 commit comments