summaryrefslogtreecommitdiff
path: root/libcxx/include/__algorithm
diff options
context:
space:
mode:
authorPeng Liu <winner245@hotmail.com>2025-03-19 11:36:29 -0400
committerGitHub <noreply@github.com>2025-03-19 11:36:29 -0400
commite53bea51829ee9876a2010fec1a13d740533b89a (patch)
treea6dd8c71037b43632f7c7fb473d8178bff4b83bf /libcxx/include/__algorithm
parentd7879e524fbbc4c2790dac62343444191f736f00 (diff)
[libc++] Fix ambiguous call in {ranges, std}::count (#122529)
This PR fixes an ambiguous call encountered while using the `std::ranges::count` and `std::count` algorithms with `vector<bool>` with small `size_type`s. The ambiguity arises from integral promotions during the internal bitwise arithmetic of the `count` algorithms for small integral types. This results in multiple viable candidates: `__libcpp_popcount(unsigned)`,` __libcpp_popcount(unsigned long)`, and `__libcpp_popcount(unsigned long long)`, leading to an ambiguous call error. To resolve this ambiguity, we introduce a dispatcher function, `__popcount`, which directs calls to the appropriate overloads of `__libcpp_popcount`. This closes #122528.
Diffstat (limited to 'libcxx/include/__algorithm')
-rw-r--r--libcxx/include/__algorithm/count.h10
1 files changed, 5 insertions, 5 deletions
diff --git a/libcxx/include/__algorithm/count.h b/libcxx/include/__algorithm/count.h
index cd9125779ec6..0cbe9b6e61b9 100644
--- a/libcxx/include/__algorithm/count.h
+++ b/libcxx/include/__algorithm/count.h
@@ -55,18 +55,18 @@ __count_bool(__bit_iterator<_Cp, _IsConst> __first, typename __size_difference_t
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));
- __r = std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_) & __m);
+ __storage_type __m = std::__middle_mask<__storage_type>(__clz_f - __dn, __first.__ctz_);
+ __r = std::__popcount(__storage_type(std::__invert_if<!_ToCount>(*__first.__seg_) & __m));
__n -= __dn;
++__first.__seg_;
}
// do middle whole words
for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word)
- __r += std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_));
+ __r += std::__popcount(std::__invert_if<!_ToCount>(*__first.__seg_));
// do last partial word
if (__n > 0) {
- __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
- __r += std::__libcpp_popcount(std::__invert_if<!_ToCount>(*__first.__seg_) & __m);
+ __storage_type __m = std::__trailing_mask<__storage_type>(__bits_per_word - __n);
+ __r += std::__popcount(__storage_type(std::__invert_if<!_ToCount>(*__first.__seg_) & __m));
}
return __r;
}