Skip to content

Commit cb44f8d

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

File tree

1 file changed

+54
-20
lines changed

1 file changed

+54
-20
lines changed

libcxx/include/bitset

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ private:
236236
# endif // _LIBCPP_CXX03_LANG
237237
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(false_type) const;
238238
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type) const;
239+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, false_type) const;
240+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, true_type) const;
239241
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(false_type) const;
240242
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type) const;
241243
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, false_type) const;
@@ -284,14 +286,23 @@ inline _LIBCPP_HIDE_FROM_ABI void __bitset<_N_words, _Size>::__init(unsigned lon
284286
template <size_t _N_words, size_t _Size>
285287
inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
286288
# ifndef _LIBCPP_CXX03_LANG
287-
# if __SIZEOF_SIZE_T__ == 8
288-
: __first_{__v}
289-
# elif __SIZEOF_SIZE_T__ == 4
289+
# if (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 1
290+
: __first_{static_cast<__storage_type>(__v)}
291+
# elif (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 2
292+
: __first_{static_cast<__storage_type>(__v), static_cast<__storage_type>(__v >> __bits_per_word)}
293+
# elif (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 4
294+
# if _N_words == 2
295+
: __first_{static_cast<__storage_type>(__v), static_cast<__storage_type>(__v >> __bits_per_word)}
296+
# elif _N_words == 3
290297
: __first_{static_cast<__storage_type>(__v),
291-
_Size >= 2 * __bits_per_word
292-
? static_cast<__storage_type>(__v >> __bits_per_word)
293-
: static_cast<__storage_type>((__v >> __bits_per_word) &
294-
(__storage_type(1) << (_Size - __bits_per_word)) - 1)}
298+
static_cast<__storage_type>(__v >> __bits_per_word),
299+
static_cast<__storage_type>(__v >> (__bits_per_word * 2))}
300+
# else
301+
: __first_{static_cast<__storage_type>(__v),
302+
static_cast<__storage_type>(__v >> __bits_per_word),
303+
static_cast<__storage_type>(__v >> (__bits_per_word * 2)),
304+
static_cast<__storage_type>(__v >> (__bits_per_word * 3))}
305+
# endif
295306
# else
296307
# error This constructor has not been ported to this platform
297308
# endif
@@ -345,15 +356,34 @@ __bitset<_N_words, _Size>::to_ulong(false_type) const {
345356
if (__i != __e)
346357
std::__throw_overflow_error("bitset to_ulong overflow error");
347358

348-
return __first_[0];
359+
return to_ulong(true_type());
349360
}
350361

351362
template <size_t _N_words, size_t _Size>
352363
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
353364
__bitset<_N_words, _Size>::to_ulong(true_type) const {
354-
return __first_[0];
365+
return to_ulong(true_type(), integral_constant<bool, sizeof(__storage_type) < sizeof(unsigned long)>());
366+
}
367+
368+
template <size_t _N_words, size_t _Size>
369+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
370+
__bitset<_N_words, _Size>::to_ulong(true_type, false_type) const {
371+
return static_cast<unsigned long>(__first_[0]);
355372
}
356373

374+
template <size_t _N_words, size_t _Size>
375+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
376+
__bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
377+
unsigned long __r = static_cast<unsigned long>(__first_[0]);
378+
_LIBCPP_DIAGNOSTIC_PUSH
379+
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
380+
const size_t __ul_words = sizeof(unsigned long) / sizeof(__storage_type);
381+
const size_t __n_words = _N_words < __ul_words ? _N_words : __ul_words;
382+
for (size_t __i = 1; __i < __n_words; ++__i)
383+
__r |= static_cast<unsigned long>(__first_[__i]) << (__bits_per_word * __i);
384+
_LIBCPP_DIAGNOSTIC_POP
385+
return __r;
386+
}
357387
template <size_t _N_words, size_t _Size>
358388
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
359389
__bitset<_N_words, _Size>::to_ullong(false_type) const {
@@ -374,19 +404,19 @@ __bitset<_N_words, _Size>::to_ullong(true_type) const {
374404
template <size_t _N_words, size_t _Size>
375405
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
376406
__bitset<_N_words, _Size>::to_ullong(true_type, false_type) const {
377-
return __first_[0];
407+
return static_cast<unsigned long long>(__first_[0]);
378408
}
379409

380410
template <size_t _N_words, size_t _Size>
381411
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
382412
__bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
383-
unsigned long long __r = __first_[0];
413+
unsigned long long __r = static_cast<unsigned long long>(__first_[0]);
384414
_LIBCPP_DIAGNOSTIC_PUSH
385415
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
386416
const size_t __ull_words = sizeof(unsigned long long) / sizeof(__storage_type);
387-
const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
417+
const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
388418
for (size_t __i = 1; __i < __n_words; ++__i)
389-
__r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT * __i);
419+
__r |= static_cast<unsigned long long>(__first_[__i]) << (__bits_per_word * __i);
390420
_LIBCPP_DIAGNOSTIC_POP
391421
return __r;
392422
}
@@ -497,8 +527,11 @@ inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset() _NOEXCEPT : __first_(0)
497527

498528
template <size_t _Size>
499529
inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
500-
: __first_(_Size == __bits_per_word ? static_cast<__storage_type>(__v)
501-
: static_cast<__storage_type>(__v) & ((__storage_type(1) << _Size) - 1)) {}
530+
: __first_(static_cast<__storage_type>(__v)) {
531+
// Force __bits_per_word to be instantiated to avoid "gdb.error: There is no member or method named
532+
// __bits_per_word"
533+
(void)__bits_per_word;
534+
}
502535

503536
template <size_t _Size>
504537
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
@@ -525,12 +558,12 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
525558

526559
template <size_t _Size>
527560
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::to_ulong() const {
528-
return __first_;
561+
return static_cast<unsigned long>(__first_);
529562
}
530563

531564
template <size_t _Size>
532565
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __bitset<1, _Size>::to_ullong() const {
533-
return __first_;
566+
return static_cast<unsigned long long>(__first_);
534567
}
535568

536569
template <size_t _Size>
@@ -594,8 +627,8 @@ protected:
594627

595628
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT {}
596629

597-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return 0; }
598-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return 0; }
630+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return 0UL; }
631+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return 0ULL; }
599632

600633
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return true; }
601634
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return false; }
@@ -624,7 +657,8 @@ public:
624657

625658
// 23.3.5.1 constructors:
626659
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
627-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT : __base(__v) {}
660+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT
661+
: __base(sizeof(unsigned long long) * CHAR_BIT <= _Size ? __v : __v & ((1ULL << _Size) - 1)) {}
628662
template <class _CharT, __enable_if_t<_IsCharLikeType<_CharT>::value, int> = 0>
629663
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
630664
const _CharT* __str,

0 commit comments

Comments
 (0)