Skip to content

Commit 233eeb3

Browse files
committed
Apply @frederick-vs-ja suggestions to support 16-bit platforms
1 parent c1dfd79 commit 233eeb3

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
@@ -233,6 +233,8 @@ private:
233233
# endif // _LIBCPP_CXX03_LANG
234234
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(false_type) const;
235235
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type) const;
236+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, false_type) const;
237+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, true_type) const;
236238
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(false_type) const;
237239
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type) const;
238240
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, false_type) const;
@@ -281,14 +283,23 @@ inline _LIBCPP_HIDE_FROM_ABI void __bitset<_N_words, _Size>::__init(unsigned lon
281283
template <size_t _N_words, size_t _Size>
282284
inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
283285
# ifndef _LIBCPP_CXX03_LANG
284-
# if __SIZEOF_SIZE_T__ == 8
285-
: __first_{__v}
286-
# elif __SIZEOF_SIZE_T__ == 4
286+
# if (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 1
287+
: __first_{static_cast<__storage_type>(__v)}
288+
# elif (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 2
289+
: __first_{static_cast<__storage_type>(__v), static_cast<__storage_type>(__v >> __bits_per_word)}
290+
# elif (__SIZEOF_LONG_LONG__ + __SIZEOF_SIZE_T__ - 1) / __SIZEOF_SIZE_T__ == 4
291+
# if _N_words == 2
292+
: __first_{static_cast<__storage_type>(__v), static_cast<__storage_type>(__v >> __bits_per_word)}
293+
# elif _N_words == 3
287294
: __first_{static_cast<__storage_type>(__v),
288-
_Size >= 2 * __bits_per_word
289-
? static_cast<__storage_type>(__v >> __bits_per_word)
290-
: static_cast<__storage_type>((__v >> __bits_per_word) &
291-
(__storage_type(1) << (_Size - __bits_per_word)) - 1)}
295+
static_cast<__storage_type>(__v >> __bits_per_word),
296+
static_cast<__storage_type>(__v >> (__bits_per_word * 2))}
297+
# else
298+
: __first_{static_cast<__storage_type>(__v),
299+
static_cast<__storage_type>(__v >> __bits_per_word),
300+
static_cast<__storage_type>(__v >> (__bits_per_word * 2)),
301+
static_cast<__storage_type>(__v >> (__bits_per_word * 3))}
302+
# endif
292303
# else
293304
# error This constructor has not been ported to this platform
294305
# endif
@@ -344,15 +355,34 @@ __bitset<_N_words, _Size>::to_ulong(false_type) const {
344355
if (__i != __e)
345356
__throw_overflow_error("bitset to_ulong overflow error");
346357

347-
return __first_[0];
358+
return to_ulong(true_type());
348359
}
349360

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

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

379409
template <size_t _N_words, size_t _Size>
380410
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
381411
__bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
382-
unsigned long long __r = __first_[0];
412+
unsigned long long __r = static_cast<unsigned long long>(__first_[0]);
383413
_LIBCPP_DIAGNOSTIC_PUSH
384414
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
385415
const size_t __ull_words = sizeof(unsigned long long) / sizeof(__storage_type);
386-
const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
416+
const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
387417
for (size_t __i = 1; __i < __n_words; ++__i)
388-
__r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT * __i);
418+
__r |= static_cast<unsigned long long>(__first_[__i]) << (__bits_per_word * __i);
389419
_LIBCPP_DIAGNOSTIC_POP
390420
return __r;
391421
}
@@ -494,8 +524,11 @@ inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset() _NOEXCEPT : __first_(0)
494524

495525
template <size_t _Size>
496526
inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
497-
: __first_(_Size == __bits_per_word ? static_cast<__storage_type>(__v)
498-
: static_cast<__storage_type>(__v) & ((__storage_type(1) << _Size) - 1)) {}
527+
: __first_(static_cast<__storage_type>(__v)) {
528+
// Force __bits_per_word to be instantiated to avoid "gdb.error: There is no member or method named
529+
// __bits_per_word"
530+
(void)__bits_per_word;
531+
}
499532

500533
template <size_t _Size>
501534
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
@@ -524,12 +557,12 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
524557

525558
template <size_t _Size>
526559
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::to_ulong() const {
527-
return __first_;
560+
return static_cast<unsigned long>(__first_);
528561
}
529562

530563
template <size_t _Size>
531564
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __bitset<1, _Size>::to_ullong() const {
532-
return __first_;
565+
return static_cast<unsigned long long>(__first_);
533566
}
534567

535568
template <size_t _Size>
@@ -595,8 +628,8 @@ protected:
595628

596629
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT {}
597630

598-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return 0; }
599-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return 0; }
631+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return 0UL; }
632+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return 0ULL; }
600633

601634
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return true; }
602635
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return false; }
@@ -626,7 +659,8 @@ public:
626659

627660
// 23.3.5.1 constructors:
628661
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
629-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT : __base(__v) {}
662+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT
663+
: __base(sizeof(unsigned long long) * CHAR_BIT <= _Size ? __v : __v & ((1ULL << _Size) - 1)) {}
630664
template <class _CharT, __enable_if_t<_IsCharLikeType<_CharT>::value, int> = 0>
631665
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
632666
const _CharT* __str,

0 commit comments

Comments
 (0)