@@ -136,6 +136,7 @@ template <size_t N> struct hash<std::bitset<N>>;
136
136
# include < __algorithm/fill.h>
137
137
# include < __algorithm/fill_n.h>
138
138
# include < __algorithm/find.h>
139
+ # include < __algorithm/min.h>
139
140
# include < __assert>
140
141
# include < __bit/countr.h>
141
142
# include < __bit/invert_if.h>
@@ -146,7 +147,11 @@ template <size_t N> struct hash<std::bitset<N>>;
146
147
# include < __functional/hash.h>
147
148
# include < __functional/identity.h>
148
149
# include < __functional/unary_function.h>
150
+ # include < __tuple/tuple_indices.h>
151
+ # include < __type_traits/enable_if.h>
152
+ # include < __type_traits/integral_constant.h>
149
153
# include < __type_traits/is_char_like_type.h>
154
+ # include < __utility/integer_sequence.h>
150
155
# include < climits>
151
156
# include < stdexcept>
152
157
# include < string_view>
@@ -220,11 +225,42 @@ protected:
220
225
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void operator ^=(const __bitset& __v) _NOEXCEPT;
221
226
222
227
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip () _NOEXCEPT;
228
+
223
229
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong () const {
224
- return to_ulong (integral_constant < bool , _Size< sizeof (unsigned long ) * CHAR_BIT>());
230
+ if _LIBCPP_CONSTEXPR (_Size > sizeof (unsigned long ) * CHAR_BIT) {
231
+ if (auto __e = __make_iter (_Size); std::find (__make_iter (sizeof (unsigned long ) * CHAR_BIT), __e, true ) != __e)
232
+ std::__throw_overflow_error (" __bitset<_N_words, _Size>::to_ulong overflow error" );
233
+ }
234
+
235
+ static_assert (sizeof (__storage_type) >= sizeof (unsigned long ),
236
+ " libc++ only supports platforms where sizeof(size_t) >= sizeof(unsigned long), such as 32-bit and "
237
+ " 64-bit platforms. If you're interested in supporting a platform where that is not the case, please "
238
+ " contact the libc++ developers." );
239
+ return static_cast <unsigned long >(__first_[0 ]);
225
240
}
241
+
226
242
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong () const {
227
- return to_ullong (integral_constant < bool , _Size< sizeof (unsigned long long ) * CHAR_BIT>());
243
+ // Check for overflow if _Size does not fit in unsigned long long
244
+ if _LIBCPP_CONSTEXPR (_Size > sizeof (unsigned long long ) * CHAR_BIT) {
245
+ if (auto __e = __make_iter (_Size);
246
+ std::find (__make_iter (sizeof (unsigned long long ) * CHAR_BIT), __e, true ) != __e)
247
+ std::__throw_overflow_error (" __bitset<_N_words, _Size>::to_ullong overflow error" );
248
+ }
249
+
250
+ // At this point, the effective bitset size (excluding leading zeros) fits in unsigned long long
251
+
252
+ if _LIBCPP_CONSTEXPR (sizeof (__storage_type) >= sizeof (unsigned long long )) {
253
+ // If __storage_type is at least as large as unsigned long long, the result spans only one word
254
+ return static_cast <unsigned long long >(__first_[0 ]);
255
+ } else {
256
+ // Otherwise, the result spans multiple words which are concatenated
257
+ const size_t __ull_words = (sizeof (unsigned long long ) - 1 ) / sizeof (__storage_type) + 1 ;
258
+ const size_t __n_words = _N_words < __ull_words ? _N_words : __ull_words;
259
+ unsigned long long __r = static_cast <unsigned long long >(__first_[0 ]);
260
+ for (size_t __i = 1 ; __i < __n_words; ++__i)
261
+ __r |= static_cast <unsigned long long >(__first_[__i]) << (__bits_per_word * __i);
262
+ return __r;
263
+ }
228
264
}
229
265
230
266
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool all () const _NOEXCEPT { return !__scan_bits (__bit_not ()); }
@@ -255,16 +291,6 @@ private:
255
291
return ~__x;
256
292
}
257
293
};
258
- # ifdef _LIBCPP_CXX03_LANG
259
- void __init (unsigned long long __v, false_type) _NOEXCEPT;
260
- _LIBCPP_HIDE_FROM_ABI void __init (unsigned long long __v, true_type) _NOEXCEPT;
261
- # endif // _LIBCPP_CXX03_LANG
262
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong (false_type) const ;
263
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong (true_type) const ;
264
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong (false_type) const ;
265
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong (true_type) const ;
266
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong (true_type, false_type) const ;
267
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong (true_type, true_type) const ;
268
294
269
295
template <typename _Proj>
270
296
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __scan_bits (_Proj __proj) const _NOEXCEPT {
@@ -282,6 +308,15 @@ private:
282
308
}
283
309
return false ;
284
310
}
311
+
312
+ # ifdef _LIBCPP_CXX03_LANG
313
+ void __init (unsigned long long __v, false_type) _NOEXCEPT;
314
+ _LIBCPP_HIDE_FROM_ABI void __init (unsigned long long __v, true_type) _NOEXCEPT;
315
+ # else
316
+ template <size_t ... _Indices>
317
+ _LIBCPP_HIDE_FROM_ABI constexpr __bitset (unsigned long long __v, std::__tuple_indices<_Indices...>) _NOEXCEPT
318
+ : __first_{static_cast <__storage_type>(__v >> (_Indices * __bits_per_word))...} {}
319
+ # endif // _LIBCPP_CXX03_LANG
285
320
};
286
321
287
322
template <size_t _N_words, size_t _Size>
@@ -316,21 +351,15 @@ inline _LIBCPP_HIDE_FROM_ABI void __bitset<_N_words, _Size>::__init(unsigned lon
316
351
template <size_t _N_words, size_t _Size>
317
352
inline _LIBCPP_CONSTEXPR __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
318
353
# ifndef _LIBCPP_CXX03_LANG
319
- # if __SIZEOF_SIZE_T__ == 8
320
- : __first_{__v}
321
- # elif __SIZEOF_SIZE_T__ == 4
322
- : __first_{static_cast <__storage_type>(__v),
323
- _Size >= 2 * __bits_per_word
324
- ? static_cast <__storage_type>(__v >> __bits_per_word)
325
- : static_cast <__storage_type>((__v >> __bits_per_word) &
326
- (__storage_type (1 ) << (_Size - __bits_per_word)) - 1 )}
327
- # else
328
- # error This constructor has not been ported to this platform
329
- # endif
354
+ : __bitset(__v,
355
+ std::__make_indices_imp< (_N_words < (sizeof (unsigned long long ) - 1 ) / sizeof (__storage_type) + 1 )
356
+ ? _N_words
357
+ : (sizeof (unsigned long long ) - 1 ) / sizeof (__storage_type) + 1 ,
358
+ 0 >{})
330
359
# endif
331
360
{
332
361
# ifdef _LIBCPP_CXX03_LANG
333
- __init (__v, integral_constant< bool , sizeof (unsigned long long ) <= sizeof (__storage_type)>());
362
+ __init (__v, _BoolConstant< sizeof (unsigned long long ) <= sizeof (__storage_type)>());
334
363
# endif
335
364
}
336
365
@@ -369,58 +398,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<_N_words, _Siz
369
398
*__p ^= (__storage_type (1 ) << __n) - 1 ;
370
399
}
371
400
372
- template <size_t _N_words, size_t _Size>
373
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
374
- __bitset<_N_words, _Size>::to_ulong(false_type) const {
375
- __const_iterator __e = __make_iter (_Size);
376
- __const_iterator __i = std::find (__make_iter (sizeof (unsigned long ) * CHAR_BIT), __e, true );
377
- if (__i != __e)
378
- std::__throw_overflow_error (" bitset to_ulong overflow error" );
379
-
380
- return __first_[0 ];
381
- }
382
-
383
- template <size_t _N_words, size_t _Size>
384
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long
385
- __bitset<_N_words, _Size>::to_ulong(true_type) const {
386
- return __first_[0 ];
387
- }
388
-
389
- template <size_t _N_words, size_t _Size>
390
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
391
- __bitset<_N_words, _Size>::to_ullong(false_type) const {
392
- __const_iterator __e = __make_iter (_Size);
393
- __const_iterator __i = std::find (__make_iter (sizeof (unsigned long long ) * CHAR_BIT), __e, true );
394
- if (__i != __e)
395
- std::__throw_overflow_error (" bitset to_ullong overflow error" );
396
-
397
- return to_ullong (true_type ());
398
- }
399
-
400
- template <size_t _N_words, size_t _Size>
401
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
402
- __bitset<_N_words, _Size>::to_ullong(true_type) const {
403
- return to_ullong (true_type (), integral_constant<bool , sizeof (__storage_type) < sizeof (unsigned long long )>());
404
- }
405
-
406
- template <size_t _N_words, size_t _Size>
407
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
408
- __bitset<_N_words, _Size>::to_ullong(true_type, false_type) const {
409
- return __first_[0 ];
410
- }
411
-
412
- template <size_t _N_words, size_t _Size>
413
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long
414
- __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const {
415
- unsigned long long __r = __first_[0 ];
416
- _LIBCPP_DIAGNOSTIC_PUSH
417
- _LIBCPP_GCC_DIAGNOSTIC_IGNORED (" -Wshift-count-overflow" )
418
- for (size_t __i = 1 ; __i < sizeof (unsigned long long ) / sizeof (__storage_type); ++__i)
419
- __r |= static_cast <unsigned long long >(__first_[__i]) << (sizeof (__storage_type) * CHAR_BIT);
420
- _LIBCPP_DIAGNOSTIC_POP
421
- return __r;
422
- }
423
-
424
401
template <size_t _N_words, size_t _Size>
425
402
inline size_t __bitset<_N_words, _Size>::__hash_code() const _NOEXCEPT {
426
403
size_t __h = 0 ;
@@ -479,8 +456,25 @@ protected:
479
456
480
457
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void flip () _NOEXCEPT;
481
458
482
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong () const ;
483
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong () const ;
459
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong () const {
460
+ if _LIBCPP_CONSTEXPR (_Size > sizeof (unsigned long ) * CHAR_BIT) {
461
+ if (auto __e = __make_iter (_Size); std::find (__make_iter (sizeof (unsigned long ) * CHAR_BIT), __e, true ) != __e)
462
+ __throw_overflow_error (" __bitset<1, _Size>::to_ulong overflow error" );
463
+ }
464
+ return static_cast <unsigned long >(__first_);
465
+ }
466
+
467
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong () const {
468
+ // If _Size exceeds the size of unsigned long long, check for overflow
469
+ if _LIBCPP_CONSTEXPR (_Size > sizeof (unsigned long long ) * CHAR_BIT) {
470
+ if (auto __e = __make_iter (_Size);
471
+ std::find (__make_iter (sizeof (unsigned long long ) * CHAR_BIT), __e, true ) != __e)
472
+ __throw_overflow_error (" __bitset<1, _Size>::to_ullong overflow error" );
473
+ }
474
+
475
+ // If _Size fits or no overflow, directly cast to unsigned long long
476
+ return static_cast <unsigned long long >(__first_);
477
+ }
484
478
485
479
template <bool _Sparse, class _CharT , class _Traits , class _Allocator >
486
480
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
@@ -507,8 +501,10 @@ inline _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset() _NOEXCEPT : __first_(0)
507
501
508
502
template <size_t _Size>
509
503
inline _LIBCPP_CONSTEXPR __bitset<1 , _Size>::__bitset(unsigned long long __v) _NOEXCEPT
510
- : __first_(_Size == __bits_per_word ? static_cast <__storage_type>(__v)
511
- : static_cast <__storage_type>(__v) & ((__storage_type(1 ) << _Size) - 1 )) {}
504
+ // TODO: We must refer to __bits_per_word in order to work around an issue with the GDB pretty-printers.
505
+ // Without it, the pretty-printers complain about a missing __bits_per_word member. This needs to
506
+ // be investigated further.
507
+ : __first_(_Size == __bits_per_word ? static_cast <__storage_type>(__v) : static_cast <__storage_type>(__v)) {}
512
508
513
509
template <size_t _Size>
514
510
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
@@ -533,16 +529,6 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void __bitset<1, _Siz
533
529
__first_ ^= ~__storage_type (0 ) >> (__bits_per_word - _Size);
534
530
}
535
531
536
- template <size_t _Size>
537
- inline _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long __bitset<1 , _Size>::to_ulong() const {
538
- return __first_;
539
- }
540
-
541
- template <size_t _Size>
542
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long __bitset<1 , _Size>::to_ullong() const {
543
- return __first_;
544
- }
545
-
546
532
template <size_t _Size>
547
533
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bool __bitset<1 , _Size>::all() const _NOEXCEPT {
548
534
__storage_type __m = ~__storage_type (0 ) >> (__bits_per_word - _Size);
@@ -633,8 +619,6 @@ class bitset : private __bitset<_Size == 0 ? 0 : (_Size - 1) / (sizeof(size_t) *
633
619
public:
634
620
static const unsigned __n_words = _Size == 0 ? 0 : (_Size - 1 ) / (sizeof (size_t ) * CHAR_BIT) + 1 ;
635
621
typedef __bitset<__n_words, _Size> __base;
636
-
637
- public:
638
622
typedef typename __base::reference reference;
639
623
typedef typename __base::__const_reference __const_reference;
640
624
@@ -713,8 +697,10 @@ public:
713
697
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (__p < _Size, " bitset::operator[] index out of bounds" );
714
698
return __base::__make_ref (__p);
715
699
}
716
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong () const ;
717
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong () const ;
700
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong () const { return __base::to_ulong (); }
701
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long to_ullong () const {
702
+ return __base::to_ullong ();
703
+ }
718
704
template <class _CharT , class _Traits , class _Allocator >
719
705
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
720
706
to_string (_CharT __zero = _CharT(' 0' ), _CharT __one = _CharT(' 1' )) const ;
@@ -850,16 +836,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 bitset<_Size>& bitset<_Size>
850
836
return *this ;
851
837
}
852
838
853
- template <size_t _Size>
854
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long bitset<_Size>::to_ulong() const {
855
- return __base::to_ulong ();
856
- }
857
-
858
- template <size_t _Size>
859
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long long bitset<_Size>::to_ullong() const {
860
- return __base::to_ullong ();
861
- }
862
-
863
839
template <size_t _Size>
864
840
template <class _CharT , class _Traits , class _Allocator >
865
841
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 basic_string<_CharT, _Traits, _Allocator>
0 commit comments