Skip to content

Commit 649cbcc

Browse files
authored
[libc++] Remove unnecessary division and modulo operations in bitset (#121312)
The PR removes the unnecessary division and modulo operations in the one-word specialization `__bitset<1, _Size>`. The reason is that for the one-word specialization, we have `__pos < __bits_per_word` (as `__bitset<1, _Size>` is an implementation detail only used by the public `bitset`). So `__pos / __bits_per_word == 0` and `__pos / __pos % __bits_per_word == __pos`.
1 parent ac8e18c commit 649cbcc

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

libcxx/include/__bit_reference

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ public:
329329
}
330330

331331
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT {
332+
_LIBCPP_ASSERT_INTERNAL(__ctz_ < __bits_per_word, "Dereferencing an invalid __bit_iterator.");
332333
return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >(
333334
__seg_, __storage_type(1) << __ctz_);
334335
}
@@ -453,7 +454,10 @@ private:
453454
_LIBCPP_HIDE_FROM_ABI
454455
_LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT
455456
: __seg_(__s),
456-
__ctz_(__ctz) {}
457+
__ctz_(__ctz) {
458+
_LIBCPP_ASSERT_INTERNAL(
459+
__ctz_ < __bits_per_word, "__bit_iterator initialized with an invalid number of trailing zeros.");
460+
}
457461

458462
friend typename _Cp::__self;
459463

libcxx/include/bitset

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,10 +464,14 @@ protected:
464464
return __const_reference(&__first_, __storage_type(1) << __pos);
465465
}
466466
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __iterator __make_iter(size_t __pos) _NOEXCEPT {
467-
return __iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);
467+
// Allow the == case to accommodate the past-the-end iterator.
468+
_LIBCPP_ASSERT_INTERNAL(__pos <= __bits_per_word, "Out of bounds access in the single-word bitset implementation.");
469+
return __pos != __bits_per_word ? __iterator(&__first_, __pos) : __iterator(&__first_ + 1, 0);
468470
}
469471
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __const_iterator __make_iter(size_t __pos) const _NOEXCEPT {
470-
return __const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);
472+
// Allow the == case to accommodate the past-the-end iterator.
473+
_LIBCPP_ASSERT_INTERNAL(__pos <= __bits_per_word, "Out of bounds access in the single-word bitset implementation.");
474+
return __pos != __bits_per_word ? __const_iterator(&__first_, __pos) : __const_iterator(&__first_ + 1, 0);
471475
}
472476

473477
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator&=(const __bitset& __v) _NOEXCEPT;

0 commit comments

Comments
 (0)