[libcxx-commits] [libcxx] [libc++] Fix ambiguous call in {ranges, std}::find (PR #122641)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Feb 11 01:03:50 PST 2025
================
@@ -38,29 +40,82 @@ _LIBCPP_BEGIN_NAMESPACE_STD
return __builtin_ctzll(__x);
}
+#ifndef _LIBCPP_CXX03_LANG
+// constexpr implementation for C++11 and later
+
+// Precondition: __t != 0 (the caller __countr_zero handles __t == 0 as a special case)
template <class _Tp>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countr_zero(_Tp __t) _NOEXCEPT {
-#if __has_builtin(__builtin_ctzg)
- return __builtin_ctzg(__t, numeric_limits<_Tp>::digits);
-#else // __has_builtin(__builtin_ctzg)
- if (__t == 0)
- return numeric_limits<_Tp>::digits;
- if (sizeof(_Tp) <= sizeof(unsigned int))
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI constexpr int __countr_zero_impl(_Tp __t) _NOEXCEPT {
+ static_assert(is_unsigned<_Tp>::value, "__countr_zero_impl only works with unsigned types");
+ if constexpr (sizeof(_Tp) <= sizeof(unsigned int)) {
return std::__libcpp_ctz(static_cast<unsigned int>(__t));
- else if (sizeof(_Tp) <= sizeof(unsigned long))
+ } else if constexpr (sizeof(_Tp) <= sizeof(unsigned long)) {
return std::__libcpp_ctz(static_cast<unsigned long>(__t));
- else if (sizeof(_Tp) <= sizeof(unsigned long long))
+ } else if constexpr (sizeof(_Tp) <= sizeof(unsigned long long)) {
return std::__libcpp_ctz(static_cast<unsigned long long>(__t));
- else {
+ } else {
+# if _LIBCPP_STD_VER == 11
+ // A recursive constexpr implementation for C++11
+ unsigned long long __ull = static_cast<unsigned long long>(__t);
+ const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
+ return __ull == 0ull ? __ulldigits + std::__countr_zero_impl<_Tp>(__t >> __ulldigits) : std::__libcpp_ctz(__ull);
+# else
int __ret = 0;
const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
while (static_cast<unsigned long long>(__t) == 0uLL) {
__ret += __ulldigits;
__t >>= __ulldigits;
}
return __ret + std::__libcpp_ctz(static_cast<unsigned long long>(__t));
+# endif
}
-#endif // __has_builtin(__builtin_ctzg)
+}
+
+#else
----------------
ldionne wrote:
Is there a reason why you had to reimplement this for C++03? Is it because you moved to `if constexpr`? If that's a feasible option, I would suggest dropping `if constexpr` but not having to provide a separate C++03 implementation. Is that doable?
https://github.com/llvm/llvm-project/pull/122641
More information about the libcxx-commits
mailing list