Skip to content

Commit afb4c9d

Browse files
committed
Apply @frederick-vs-ja suggestions to support 16-bit platforms
1 parent 5c636ec commit afb4c9d

File tree

1 file changed

+61
-24
lines changed

1 file changed

+61
-24
lines changed

libcxx/include/bitset

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,14 @@ private:
231231
void __init(unsigned long long __v, false_type) _NOEXCEPT;
232232
_LIBCPP_HIDE_FROM_ABI void __init(unsigned long long __v, true_type) _NOEXCEPT;
233233
# endif // _LIBCPP_CXX03_LANG
234+
# if _LIBCPP_STD_VER == 11
235+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
236+
__initialize(unsigned long long __v, size_t __i, size_t __n_words) _NOEXCEPT;
237+
# endif // _LIBCPP_STD_VER == 11
234238
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(false_type) const;
235239
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type) const;
240+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, false_type) const;
241+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong(true_type, true_type) const;
236242
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(false_type) const;
237243
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type) const;
238244
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong(true_type, false_type) const;
@@ -278,23 +284,34 @@ inline _LIBCPP_HIDE_FROM_ABI void __bitset<_N_words, _Size>::__init(unsigned lon
278284

279285
# endif // _LIBCPP_CXX03_LANG
280286

287+
# if _LIBCPP_STD_VER == 11
288+
template <size_t _N_words, size_t _Size>
289+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
290+
__bitset<_N_words, _Size>::__initialize(unsigned long long __v, size_t __i, size_t __n_words) _NOEXCEPT {
291+
if (__i < __n_words) {
292+
__first_[__i] = static_cast<__storage_type>(__v >> __bits_per_word * __i);
293+
return __initialize(__v, __i + 1, __n_words);
294+
}
295+
return true;
296+
}
297+
# endif
298+
281299
template <size_t _N_words, size_t _Size>
282300
inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
283301
# ifndef _LIBCPP_CXX03_LANG
284-
# if __SIZEOF_SIZE_T__ == 8
285-
: __first_{__v}
286-
# elif __SIZEOF_SIZE_T__ == 4
287-
: __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)}
292-
# else
293-
# error This constructor has not been ported to this platform
294-
# endif
302+
: __first_{static_cast<__storage_type>(__v)}
295303
# endif
296304
{
297-
# ifdef _LIBCPP_CXX03_LANG
305+
# ifndef _LIBCPP_CXX03_LANG
306+
const size_t __ull_words = sizeof(unsigned long long) / sizeof(__storage_type);
307+
const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
308+
# if _LIBCPP_STD_VER >= 14
309+
for (size_t __i = 1; __i < __n_words; ++__i)
310+
__first_[__i] = static_cast<__storage_type>(__v >> __bits_per_word * __i);
311+
# else
312+
(void)__initialize(__v, 1, __n_words);
313+
# endif
314+
# else
298315
__init(__v, integral_constant<bool, sizeof(unsigned long long) == sizeof(__storage_type)>());
299316
# endif
300317
}
@@ -344,13 +361,33 @@ __bitset<_N_words, _Size>::to_ulong(false_type) const {
344361
if (__i != __e)
345362
__throw_overflow_error("bitset to_ulong overflow error");
346363

347-
return __first_[0];
364+
return to_ulong(true_type());
348365
}
349366

350367
template <size_t _N_words, size_t _Size>
351368
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
352369
__bitset<_N_words, _Size>::to_ulong(true_type) const {
353-
return __first_[0];
370+
return to_ulong(true_type(), integral_constant<bool, sizeof(__storage_type) < sizeof(unsigned long)>());
371+
}
372+
373+
template <size_t _N_words, size_t _Size>
374+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
375+
__bitset<_N_words, _Size>::to_ulong(true_type, false_type) const {
376+
return static_cast<unsigned long>(__first_[0]);
377+
}
378+
379+
template <size_t _N_words, size_t _Size>
380+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
381+
__bitset<_N_words, _Size>::to_ulong(true_type, true_type) const {
382+
unsigned long __r = __first_[0];
383+
_LIBCPP_DIAGNOSTIC_PUSH
384+
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
385+
const size_t __ul_words = sizeof(unsigned long) / sizeof(__storage_type);
386+
const size_t __n_words = _N_words < __ul_words ? _N_words : __ul_words;
387+
for (size_t __i = 1; __i < __n_words; ++__i)
388+
__r |= static_cast<unsigned long>(__first_[__i]) << (__bits_per_word * __i);
389+
_LIBCPP_DIAGNOSTIC_POP
390+
return __r;
354391
}
355392

356393
template <size_t _N_words, size_t _Size>
@@ -373,7 +410,7 @@ __bitset<_N_words, _Size>::to_ullong(true_type) const {
373410
template <size_t _N_words, size_t _Size>
374411
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
375412
__bitset<_N_words, _Size>::to_ullong(true_type, false_type) const {
376-
return __first_[0];
413+
return static_cast<unsigned long long>(__first_[0]);
377414
}
378415

379416
template <size_t _N_words, size_t _Size>
@@ -383,9 +420,9 @@ __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
383420
_LIBCPP_DIAGNOSTIC_PUSH
384421
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshift-count-overflow")
385422
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;
423+
const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
387424
for (size_t __i = 1; __i < __n_words; ++__i)
388-
__r |= static_cast<unsigned long long>(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT * __i);
425+
__r |= static_cast<unsigned long long>(__first_[__i]) << (__bits_per_word * __i);
389426
_LIBCPP_DIAGNOSTIC_POP
390427
return __r;
391428
}
@@ -494,8 +531,7 @@ inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset() _NOEXCEPT : __first_(0)
494531

495532
template <size_t _Size>
496533
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)) {}
534+
: __first_(static_cast<__storage_type>(__v)) {}
499535

500536
template <size_t _Size>
501537
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
@@ -524,12 +560,12 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
524560

525561
template <size_t _Size>
526562
inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1, _Size>::to_ulong() const {
527-
return __first_;
563+
return static_cast<unsigned long>(__first_);
528564
}
529565

530566
template <size_t _Size>
531567
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __bitset<1, _Size>::to_ullong() const {
532-
return __first_;
568+
return static_cast<unsigned long long>(__first_);
533569
}
534570

535571
template <size_t _Size>
@@ -595,8 +631,8 @@ protected:
595631

596632
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip() _NOEXCEPT {}
597633

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; }
634+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const { return 0UL; }
635+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong() const { return 0ULL; }
600636

601637
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all() const _NOEXCEPT { return true; }
602638
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool any() const _NOEXCEPT { return false; }
@@ -626,7 +662,8 @@ public:
626662

627663
// 23.3.5.1 constructors:
628664
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
629-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT : __base(__v) {}
665+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bitset(unsigned long long __v) _NOEXCEPT
666+
: __base(sizeof(unsigned long long) * CHAR_BIT <= _Size ? __v : __v & (1ULL << _Size) - 1) {}
630667
template <class _CharT, __enable_if_t<_IsCharLikeType<_CharT>::value, int> = 0>
631668
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
632669
const _CharT* __str,

0 commit comments

Comments
 (0)