[libcxx-commits] [libcxx] [libc++] Fix bitset conversion functions and refactor constructor (PR #121348)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jun 18 09:36:10 PDT 2025


================
@@ -220,11 +225,52 @@ protected:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator^=(const __bitset& __v) _NOEXCEPT;
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT;
+
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong() const {
+    static_assert(sizeof(__storage_type) >= sizeof(unsigned long),
+                  "libc++ only supports platforms where sizeof(size_t) >= sizeof(unsigned long), such as 32-bit and "
+                  "64-bit platforms. If you're interested in supporting a platform where that is not the case, please "
+                  "contact the libc++ developers.");
+    return static_cast<unsigned long>(__first_[0]);
+  }
+
+  // _Bit_size > sizeof(unsigned long) * CHAR_BIT: overflow check needed
+  template <size_t _Bit_size = _Size, __enable_if_t<(_Bit_size > sizeof(unsigned long) * CHAR_BIT), int> = 0>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const {
-    return to_ulong(integral_constant < bool, _Size< sizeof(unsigned long) * CHAR_BIT>());
+    if (auto __e = __make_iter(_Bit_size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
+      std::__throw_overflow_error("__bitset<_N_words, _Size>::to_ulong overflow error");
----------------
ldionne wrote:

```c++
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const {
  // _Size > sizeof(unsigned long) * CHAR_BIT: overflow check needed
  if _LIBCPP_CONSTEXPR (_Size > sizeof(unsigned long long) * CHAR_BIT) {
    if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
      std::__throw_overflow_error("__bitset<_N_words, _Size>::to_ulong overflow error");
  }

  static_assert(sizeof(__storage_type) >= sizeof(unsigned long),
                "libc++ only supports platforms where sizeof(size_t) >= sizeof(unsigned long), such as 32-bit and "
                "64-bit platforms. If you're interested in supporting a platform where that is not the case, please "
                "contact the libc++ developers.");

  return static_cast<unsigned long>(__first_[0]);
}
```

Is this equivalent? If that works just as well, I think it's easier to follow.

https://github.com/llvm/llvm-project/pull/121348


More information about the libcxx-commits mailing list