[libcxx-commits] [libcxx] [libc++] Simplify bitset::{any, all} (PR #128445)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Sat May 17 08:46:31 PDT 2025


https://github.com/winner245 updated https://github.com/llvm/llvm-project/pull/128445

>From 5b6f12d58fcb740213a0461a226c2d7696675747 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Sun, 23 Feb 2025 19:11:53 -0500
Subject: [PATCH 1/2] Simplify bitset::{any, all}

---
 libcxx/include/bitset | 56 +++++++------------------------------------
 1 file changed, 8 insertions(+), 48 deletions(-)

diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index 9273ccabbb4e3..d98983d3d001a 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -224,8 +224,12 @@ 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 std::find(__make_iter(0), __make_iter(_Size), false) == __make_iter(_Size);
+  }
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT {
+    return std::find(__make_iter(0), __make_iter(_Size), true) != __make_iter(_Size);
+  }
   _LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
 
 private:
@@ -388,40 +392,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;
@@ -716,8 +686,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;
@@ -903,16 +873,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 {

>From 669261f53158b3c0b0ac39cbd12cc3caca7e5c70 Mon Sep 17 00:00:00 2001
From: Peng Liu <winner245 at hotmail.com>
Date: Sat, 17 May 2025 11:45:37 -0400
Subject: [PATCH 2/2] Refactor any and all

---
 libcxx/include/bitset | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/bitset b/libcxx/include/bitset
index d98983d3d001a..046420dd5d5d3 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -142,6 +142,7 @@ template <size_t N> struct hash<std::bitset<N>>;
 #  include <__cstddef/ptrdiff_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>
@@ -225,10 +226,10 @@ protected:
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT {
-    return std::find(__make_iter(0), __make_iter(_Size), false) == __make_iter(_Size);
+    return __scan_bits<false>(__bit_not());
   }
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT {
-    return std::find(__make_iter(0), __make_iter(_Size), true) != __make_iter(_Size);
+    return __scan_bits<true>(std::__identity());
   }
   _LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
 
@@ -243,6 +244,33 @@ 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 <bool _Early_return, typename _Proj>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 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 _Early_return;
+      }
+    }
+    // do last partial word
+    if (__n > 0) {
+      __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n);
+      if (__proj(*__p) & __m) {
+        return _Early_return;
+      }
+    }
+    return !_Early_return;
+  }
+
+  struct __bit_not {
+    template <class _Tp>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp operator()(const _Tp& __x) const _NOEXCEPT {
+      return ~__x;
+    }
+  };
 };
 
 template <size_t _N_words, size_t _Size>



More information about the libcxx-commits mailing list