Skip to content

Commit d820b2c

Browse files
committed
[libc++] Use _BitInt and __builtin_popcountg in bitset::count()
1 parent c5ded52 commit d820b2c

File tree

2 files changed

+12
-1
lines changed

2 files changed

+12
-1
lines changed

libcxx/include/__bit/popcount.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ _LIBCPP_PUSH_MACROS
2121

2222
_LIBCPP_BEGIN_NAMESPACE_STD
2323

24+
static_assert(__is_unsigned_integer_v<unsigned _BitInt(10)>);
25+
2426
template <class _Tp>
2527
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __popcount(_Tp __t) _NOEXCEPT {
2628
static_assert(__is_unsigned_integer_v<_Tp>, "__popcount only works with unsigned types");

libcxx/include/bitset

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,16 @@ bitset<_Size>::to_string(char __zero, char __one) const {
867867

868868
template <size_t _Size>
869869
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 size_t bitset<_Size>::count() const _NOEXCEPT {
870-
return static_cast<size_t>(std::count(__base::__make_iter(0), __base::__make_iter(_Size), true));
870+
# if defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG)
871+
if constexpr (_Size == 0) {
872+
return 0;
873+
} else if constexpr (_Size <= __base::__bits_per_word) {
874+
return __builtin_popcountg(static_cast<unsigned _BitInt(_Size)>(__base::__first_));
875+
} else
876+
# endif
877+
{
878+
return static_cast<size_t>(std::count(__base::__make_iter(0), __base::__make_iter(_Size), true));
879+
}
871880
}
872881

873882
template <size_t _Size>

0 commit comments

Comments
 (0)