Skip to content

Commit a27472c

Browse files
committed
Fix to_ulong to throw overflow_error as expected
1 parent 8966964 commit a27472c

File tree

1 file changed

+46
-25
lines changed

1 file changed

+46
-25
lines changed

libcxx/include/bitset

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,10 @@ protected:
223223

224224
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT;
225225
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const {
226-
return to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
226+
return __to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
227227
}
228228
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const {
229-
return to_ullong(_BoolConstant < _Size< sizeof(unsigned long long) * CHAR_BIT>());
229+
return __to_ullong(_BoolConstant < _Size< sizeof(unsigned long long) * CHAR_BIT>());
230230
}
231231

232232
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return !__scan_bits(__bit_not()); }
@@ -261,14 +261,6 @@ private:
261261
void __init(unsigned long long __v, false_type) _NOEXCEPT;
262262
_LIBCPP_HIDE_FROM_ABI void __init(unsigned long long __v, true_type) _NOEXCEPT;
263263
# endif // _LIBCPP_CXX03_LANG
264-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(false_type) const;
265-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type) const;
266-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, false_type) const;
267-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, true_type) const;
268-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(false_type) const;
269-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type) const;
270-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, false_type) const;
271-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, true_type) const;
272264

273265
template <typename _Proj>
274266
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __scan_bits(_Proj __proj) const _NOEXCEPT {
@@ -286,6 +278,15 @@ private:
286278
}
287279
return false;
288280
}
281+
282+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(false_type) const;
283+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type) const;
284+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type, false_type) const;
285+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type, true_type) const;
286+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(false_type) const;
287+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(true_type) const;
288+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(true_type, false_type) const;
289+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __to_ullong(true_type, true_type) const;
289290
};
290291

291292
template <size_t _N_words, size_t _Size>
@@ -384,28 +385,28 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<_N_words, _Siz
384385

385386
template <size_t _N_words, size_t _Size>
386387
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
387-
__bitset<_N_words, _Size>::to_ulong(false_type) const {
388+
__bitset<_N_words, _Size>::__to_ulong(false_type) const {
388389
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
389-
std::__throw_overflow_error("bitset to_ulong overflow error");
390+
std::__throw_overflow_error("bitset __to_ulong overflow error");
390391

391-
return to_ulong(true_type());
392+
return __to_ulong(true_type());
392393
}
393394

394395
template <size_t _N_words, size_t _Size>
395396
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
396-
__bitset<_N_words, _Size>::to_ulong(true_type) const {
397-
return to_ulong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long)>());
397+
__bitset<_N_words, _Size>::__to_ulong(true_type) const {
398+
return __to_ulong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long)>());
398399
}
399400

400401
template <size_t _N_words, size_t _Size>
401402
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
402-
__bitset<_N_words, _Size>::to_ulong(true_type, false_type) const {
403+
__bitset<_N_words, _Size>::__to_ulong(true_type, false_type) const {
403404
return static_cast<unsigned long>(__first_[0]);
404405
}
405406

406407
template <size_t _N_words, size_t _Size>
407408
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
408-
__bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
409+
__bitset<_N_words, _Size>::__to_ulong(true_type, true_type) const {
409410
unsigned long __r = static_cast<unsigned long>(__first_[0]);
410411
_LIBCPP_DIAGNOSTIC_PUSH
411412
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
@@ -414,34 +415,37 @@ __bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
414415
_LIBCPP_DIAGNOSTIC_POP
415416
return __r;
416417
}
418+
417419
template <size_t _N_words, size_t _Size>
418420
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
419-
__bitset<_N_words, _Size>::to_ullong(false_type) const {
421+
__bitset<_N_words, _Size>::__to_ullong(false_type) const {
420422
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true) != __e)
421-
std::__throw_overflow_error("bitset to_ullong overflow error");
423+
std::__throw_overflow_error("bitset __to_ullong overflow error");
422424

423-
return to_ullong(true_type());
425+
return __to_ullong(true_type());
424426
}
425427

426428
template <size_t _N_words, size_t _Size>
427429
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
428-
__bitset<_N_words, _Size>::to_ullong(true_type) const {
429-
return to_ullong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long long)>());
430+
__bitset<_N_words, _Size>::__to_ullong(true_type) const {
431+
return __to_ullong(true_type(), _BoolConstant<sizeof(__storage_type) < sizeof(unsigned long long)>());
430432
}
431433

432434
template <size_t _N_words, size_t _Size>
433435
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
434-
__bitset<_N_words, _Size>::to_ullong(true_type, false_type) const {
436+
__bitset<_N_words, _Size>::__to_ullong(true_type, false_type) const {
435437
return static_cast<unsigned long long>(__first_[0]);
436438
}
437439

438440
template <size_t _N_words, size_t _Size>
439441
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
440-
__bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
442+
__bitset<_N_words, _Size>::__to_ullong(true_type, true_type) const {
441443
unsigned long long __r = static_cast<unsigned long long>(__first_[0]);
442444
_LIBCPP_DIAGNOSTIC_PUSH
443445
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
444-
for (size_t __i = 1; __i < _N_words; ++__i)
446+
const size_t __ull_wrods = (sizeof(unsigned long long) - 1) / sizeof(__storage_type) + 1;
447+
const size_t __n_words = _N_words < __ull_wrods ? _N_words : __ull_wrods;
448+
for (size_t __i = 1; __i < __n_words; ++__i)
445449
__r |= static_cast<unsigned long long>(__first_[__i]) << (__bits_per_word * __i);
446450
_LIBCPP_DIAGNOSTIC_POP
447451
return __r;
@@ -526,6 +530,10 @@ protected:
526530
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT;
527531

528532
_LIBCPP_HIDE_FROM_ABI size_t __hash_code() const _NOEXCEPT;
533+
534+
private:
535+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(false_type) const;
536+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __to_ulong(true_type) const;
529537
};
530538

531539
template <size_t _Size>
@@ -560,6 +568,19 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
560568

561569
template <size_t _Size>
562570
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::to_ulong() const {
571+
return __to_ulong(_BoolConstant < _Size< sizeof(unsigned long) * CHAR_BIT>());
572+
}
573+
574+
template <size_t _Size>
575+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::__to_ulong(false_type) const {
576+
if (auto __e = __make_iter(_Size); std::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true) != __e)
577+
__throw_overflow_error("__bitset<1, _Size>::__to_ulong overflow error");
578+
579+
return static_cast<unsigned long>(__first_);
580+
}
581+
582+
template <size_t _Size>
583+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::__to_ulong(true_type) const {
563584
return static_cast<unsigned long>(__first_);
564585
}
565586

0 commit comments

Comments
 (0)