diff options
| author | Peng Liu <winner245@hotmail.com> | 2025-03-13 14:15:03 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-13 14:15:03 -0400 |
| commit | 3bd71cbec75292f188bee3aaba2dc94c8955ad66 (patch) | |
| tree | fd3d1bf0b19a004bd3d1babf6dae157554f81c01 /libcxx/include/__algorithm | |
| parent | e61859f14ddd4a1c816518676a2a6dc19ef92206 (diff) | |
[libc++] Fix ambiguous call in {ranges, std}::find (#122641)
This PR fixes an ambiguous call encountered when using the `std::ranges::find` or `std::find`
algorithms with `vector<bool>` with small `allocator_traits::size_type`s, an issue reported
in #122528. The ambiguity arises from integral promotions during the internal bitwise
arithmetic of the `find` algorithms when applied to `vector<bool>` with small integral
`size_type`s. This leads to multiple viable candidates for small integral types:
__libcpp_ctz(unsigned), __libcpp_ctz(unsigned long), and __libcpp_ctz(unsigned long long),
none of which represent a single best viable match, resulting in an ambiguous call error.
To resolve this, we propose invoking an internal function __countr_zero as a dispatcher
that directs the call to the appropriate overload of __libcpp_ctz. Necessary amendments
have also been made to __countr_zero.
Diffstat (limited to 'libcxx/include/__algorithm')
| -rw-r--r-- | libcxx/include/__algorithm/find.h | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h index 24b8b2f96443..a7d9374b3a1c 100644 --- a/libcxx/include/__algorithm/find.h +++ b/libcxx/include/__algorithm/find.h @@ -106,10 +106,10 @@ __find_bool(__bit_iterator<_Cp, _IsConst> __first, typename __size_difference_ty if (__first.__ctz_ != 0) { __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); __storage_type __dn = std::min(__clz_f, __n); - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __m = std::__middle_mask<__storage_type>(__clz_f - __dn, __first.__ctz_); __storage_type __b = std::__invert_if<!_ToFind>(*__first.__seg_) & __m; if (__b) - return _It(__first.__seg_, static_cast<unsigned>(std::__libcpp_ctz(__b))); + return _It(__first.__seg_, static_cast<unsigned>(std::__countr_zero(__b))); if (__n == __dn) return __first + __n; __n -= __dn; @@ -119,14 +119,14 @@ __find_bool(__bit_iterator<_Cp, _IsConst> __first, typename __size_difference_ty for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) { __storage_type __b = std::__invert_if<!_ToFind>(*__first.__seg_); if (__b) - return _It(__first.__seg_, static_cast<unsigned>(std::__libcpp_ctz(__b))); + return _It(__first.__seg_, static_cast<unsigned>(std::__countr_zero(__b))); } // do last partial word if (__n > 0) { - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n); __storage_type __b = std::__invert_if<!_ToFind>(*__first.__seg_) & __m; if (__b) - return _It(__first.__seg_, static_cast<unsigned>(std::__libcpp_ctz(__b))); + return _It(__first.__seg_, static_cast<unsigned>(std::__countr_zero(__b))); } return _It(__first.__seg_, static_cast<unsigned>(__n)); } |
