[libcxx-commits] [libcxx] [libc++] Fix ambiguous call in {ranges, std}::find (PR #122641)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Tue Feb 11 20:54:34 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);
----------------
winner245 wrote:

Yes, loops are not supported in C++11 constexpr function, even with clang's ompiler extension. Clang does provide many C++14 constexpr extentions in C++11 mode. For example, clang allows variable declarations in a C++11 constexpr function via the C++14 extension. However, it does not support loops in C++11 constexpr function. 

This [demo ](https://godbolt.org/z/Yx6vd9Tn3) clearly demonstrates that:
- Clang supports `if constexpr` in C++11 mode as a C++17 extension.
- Clang supports variable declarations in C++11 `constexpr` functions as a C++14 extension.
- Clang supports multiple return statements in C++11 `constexpr` functions as a C++14 extension.
- Clang does not allow loops in C++11 `constexpr` functions.

https://github.com/llvm/llvm-project/pull/122641


More information about the libcxx-commits mailing list