Skip to content

Commit e1fb50d

Browse files
committed
Apply @frederick-vs-ja suggestions to support 16-bit platforms
1 parent 1b3c154 commit e1fb50d

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

libcxx/include/bitset

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ private:
262262
# endif // _LIBCPP_CXX03_LANG
263263
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(false_type) const;
264264
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type) const;
265+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, false_type) const;
266+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, true_type) const;
265267
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(false_type) const;
266268
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type) const;
267269
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, false_type) const;
@@ -317,14 +319,23 @@ inline _LIBCPP_HIDE_FROM_ABI void __bitset<_N_words, _Size>::__init(unsigned lon
317319
template <size_t _N_words, size_t _Size>
318320
inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
319321
# ifndef _LIBCPP_CXX03_LANG
320-
# if __SIZEOF_SIZE_T__ == 8
321-
: __first_{__v}
322-
# elif __SIZEOF_SIZE_T__ == 4
322+
# if (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 1
323+
: __first_{static_cast<__storage_type>(__v)}
324+
# elif (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 2
325+
: __first_{static_cast<__storage_type>(__v), static_cast<__storage_type>(__v >> __bits_per_word)}
326+
# elif (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 4
327+
# if _N_words == 2
328+
: __first_{static_cast<__storage_type>(__v), static_cast<__storage_type>(__v >> __bits_per_word)}
329+
# elif _N_words == 3
323330
: __first_{static_cast<__storage_type>(__v),
324-
_Size >= 2 * __bits_per_word
325-
? static_cast<__storage_type>(__v >> __bits_per_word)
326-
: static_cast<__storage_type>((__v >> __bits_per_word) &
327-
(__storage_type(1) << (_Size - __bits_per_word)) - 1)}
331+
static_cast<__storage_type>(__v >> __bits_per_word),
332+
static_cast<__storage_type>(__v >> (__bits_per_word * 2))}
333+
# else
334+
: __first_{static_cast<__storage_type>(__v),
335+
static_cast<__storage_type>(__v >> __bits_per_word),
336+
static_cast<__storage_type>(__v >> (__bits_per_word * 2)),
337+
static_cast<__storage_type>(__v >> (__bits_per_word * 3))}
338+
# endif
328339
# else
329340
# error This constructor has not been ported to this platform
330341
# endif
@@ -378,15 +389,34 @@ __bitset<_N_words, _Size>::to_ulong(false_type) const {
378389
if (__i != __e)
379390
std::__throw_overflow_error("bitset to_ulong overflow error");
380391

381-
return __first_[0];
392+
return to_ulong(true_type());
382393
}
383394

384395
template <size_t _N_words, size_t _Size>
385396
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
386397
__bitset<_N_words, _Size>::to_ulong(true_type) const {
387-
return __first_[0];
398+
return to_ulong(true_type(), integral_constant<bool, sizeof(__storage_type) < sizeof(unsigned long)>());
399+
}
400+
401+
template <size_t _N_words, size_t _Size>
402+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
403+
__bitset<_N_words, _Size>::to_ulong(true_type, false_type) const {
404+
return static_cast<unsigned long>(__first_[0]);
388405
}
389406

407+
template <size_t _N_words, size_t _Size>
408+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
409+
__bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
410+
unsigned long __r = static_cast<unsigned long>(__first_[0]);
411+
_LIBCPP_DIAGNOSTIC_PUSH
412+
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
413+
const size_t __ul_words = sizeof(unsigned long) / sizeof(__storage_type);
414+
const size_t __n_words = _N_words < __ul_words ? _N_words : __ul_words;
415+
for (size_t __i = 1; __i < __n_words; ++__i)
416+
__r |= static_cast<unsigned long>(__first_[__i]) << (__bits_per_word * __i);
417+
_LIBCPP_DIAGNOSTIC_POP
418+
return __r;
419+
}
390420
template <size_t _N_words, size_t _Size>
391421
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
392422
__bitset<_N_words, _Size>::to_ullong(false_type) const {
@@ -407,19 +437,19 @@ __bitset<_N_words, _Size>::to_ullong(true_type) const {
407437
template <size_t _N_words, size_t _Size>
408438
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
409439
__bitset<_N_words, _Size>::to_ullong(true_type, false_type) const {
410-
return __first_[0];
440+
return static_cast<unsigned long long>(__first_[0]);
411441
}
412442

413443
template <size_t _N_words, size_t _Size>
414444
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
415445
__bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
416-
unsigned long long __r = __first_[0];
446+
unsigned long long __r = static_cast<unsigned long long>(__first_[0]);
417447
_LIBCPP_DIAGNOSTIC_PUSH
418448
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
419449
const size_t __ull_words = sizeof(unsigned long long) / sizeof(__storage_type);
420-
const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
450+
const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
421451
for (size_t __i = 1; __i < __n_words; ++__i)
422-
__r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT * __i);
452+
__r |= static_cast<unsigned long long>(__first_[__i]) << (__bits_per_word * __i);
423453
_LIBCPP_DIAGNOSTIC_POP
424454
return __r;
425455
}
@@ -510,8 +540,11 @@ inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset() _NOEXCEPT : __first_(0)
510540

511541
template <size_t _Size>
512542
inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
513-
: __first_(_Size == __bits_per_word ? static_cast<__storage_type>(__v)
514-
: static_cast<__storage_type>(__v) & ((__storage_type(1) << _Size) - 1)) {}
543+
: __first_(static_cast<__storage_type>(__v)) {
544+
// Force __bits_per_word to be instantiated to avoid "gdb.error: There is no member or method named
545+
// __bits_per_word"
546+
(void)__bits_per_word;
547+
}
515548

516549
template <size_t _Size>
517550
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
@@ -538,12 +571,12 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
538571

539572
template <size_t _Size>
540573
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::to_ulong() const {
541-
return __first_;
574+
return static_cast<unsigned long>(__first_);
542575
}
543576

544577
template <size_t _Size>
545578
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __bitset<1, _Size>::to_ullong() const {
546-
return __first_;
579+
return static_cast<unsigned long long>(__first_);
547580
}
548581

549582
template <size_t _Size>
@@ -607,8 +640,8 @@ protected:
607640

608641
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT {}
609642

610-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return 0; }
611-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return 0; }
643+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return 0UL; }
644+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return 0ULL; }
612645

613646
template <bool _Sparse, class _CharT, class _Traits, class _Allocator>
614647
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>

0 commit comments

Comments
 (0)