[libcxx-commits] [libcxx] 4ad230b - [libc++] Refactor bitset::{any, all} (#128445)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed May 28 09:11:04 PDT 2025
Author: Peng Liu
Date: 2025-05-28T12:10:46-04:00
New Revision: 4ad230bebd1dcdf09f445181f34e8fa92e970412
URL: https://github.com/llvm/llvm-project/commit/4ad230bebd1dcdf09f445181f34e8fa92e970412
DIFF: https://github.com/llvm/llvm-project/commit/4ad230bebd1dcdf09f445181f34e8fa92e970412.diff
LOG: [libc++] Refactor bitset::{any, all} (#128445)
This patch refactors the `all()` and `any()` methods in `bitset` to
eliminate redundant code while preserving the performance. Code
generation remains unchanged, as verified on Compiler
Explorer: https://godbolt.org/z/xx8hb4sPM.
Added:
Modified:
libcxx/include/bitset
Removed:
################################################################################
diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index 13ad31f5f924f..88dc0e08c995d 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -144,6 +144,7 @@ template <size_t N> struct hash<std::bitset<N>>;
# include <__cstddef/ptr
diff _t.h>
# include <__cstddef/size_t.h>
# include <__functional/hash.h>
+# include <__functional/identity.h>
# include <__functional/unary_function.h>
# include <__type_traits/is_char_like_type.h>
# include <climits>
@@ -226,8 +227,10 @@ protected:
return to_ullong(integral_constant < bool, _Size< sizeof(unsigned long long) * CHAR_BIT>());
}
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return !__scan_bits(__bit_not()); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT {
+ return __scan_bits(std::__identity());
+ }
_LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
template <bool _Sparse, class _CharT, class _Traits, class _Allocator>
@@ -246,6 +249,12 @@ protected:
}
private:
+ struct __bit_not {
+ template <class _Tp>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp operator()(const _Tp& __x) const _NOEXCEPT {
+ return ~__x;
+ }
+ };
# ifdef _LIBCPP_CXX03_LANG
void __init(unsigned long long __v, false_type) _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI void __init(unsigned long long __v, true_type) _NOEXCEPT;
@@ -256,6 +265,23 @@ private:
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type) const;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, false_type) const;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, true_type) const;
+
+ template <typename _Proj>
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __scan_bits(_Proj __proj) const _NOEXCEPT {
+ size_t __n = _Size;
+ __const_storage_pointer __p = __first_;
+ // do middle whole words
+ for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
+ if (__proj(*__p))
+ return true;
+ // do last partial word
+ if (__n > 0) {
+ __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+ if (__proj(*__p) & __m)
+ return true;
+ }
+ return false;
+ }
};
template <size_t _N_words, size_t _Size>
@@ -395,40 +421,6 @@ __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
return __r;
}
-template <size_t _N_words, size_t _Size>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<_N_words, _Size>::all() const _NOEXCEPT {
- // do middle whole words
- size_t __n = _Size;
- __const_storage_pointer __p = __first_;
- for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
- if (~*__p)
- return false;
- // do last partial word
- if (__n > 0) {
- __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
- if (~*__p & __m)
- return false;
- }
- return true;
-}
-
-template <size_t _N_words, size_t _Size>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<_N_words, _Size>::any() const _NOEXCEPT {
- // do middle whole words
- size_t __n = _Size;
- __const_storage_pointer __p = __first_;
- for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word)
- if (*__p)
- return true;
- // do last partial word
- if (__n > 0) {
- __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
- if (*__p & __m)
- return true;
- }
- return false;
-}
-
template <size_t _N_words, size_t _Size>
inline size_t __bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT {
size_t __h = 0;
@@ -744,8 +736,8 @@ public:
_LIBCPP_HIDE_FROM_ABI bool operator!=(const bitset& __rhs) const _NOEXCEPT;
# endif
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool test(size_t __pos) const;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT;
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return __base::all(); }
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return __base::any(); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool none() const _NOEXCEPT { return !any(); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator<<(size_t __pos) const _NOEXCEPT;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset operator>>(size_t __pos) const _NOEXCEPT;
@@ -930,16 +922,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool bitset<_Size>::test(siz
return (*this)[__pos];
}
-template <size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool bitset<_Size>::all() const _NOEXCEPT {
- return __base::all();
-}
-
-template <size_t _Size>
-inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool bitset<_Size>::any() const _NOEXCEPT {
- return __base::any();
-}
-
template <size_t _Size>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>
bitset<_Size>::operator<<(size_t __pos) const _NOEXCEPT {
More information about the libcxx-commits
mailing list