|
10 | 10 | #ifndef _LIBCPP___BIT_REFERENCE
|
11 | 11 | #define _LIBCPP___BIT_REFERENCE
|
12 | 12 |
|
| 13 | +#include <__algorithm/comp.h> |
13 | 14 | #include <__algorithm/copy.h>
|
14 | 15 | #include <__algorithm/copy_backward.h>
|
15 | 16 | #include <__algorithm/copy_n.h>
|
| 17 | +#include <__algorithm/equal.h> |
16 | 18 | #include <__algorithm/min.h>
|
17 | 19 | #include <__assert>
|
18 | 20 | #include <__bit/countr.h>
|
19 | 21 | #include <__compare/ordering.h>
|
20 | 22 | #include <__config>
|
21 | 23 | #include <__cstddef/ptrdiff_t.h>
|
22 | 24 | #include <__cstddef/size_t.h>
|
| 25 | +#include <__functional/identity.h> |
23 | 26 | #include <__fwd/bit_reference.h>
|
24 | 27 | #include <__iterator/iterator_traits.h>
|
25 | 28 | #include <__memory/construct_at.h>
|
26 | 29 | #include <__memory/pointer_traits.h>
|
27 | 30 | #include <__type_traits/conditional.h>
|
| 31 | +#include <__type_traits/desugars_to.h> |
28 | 32 | #include <__type_traits/enable_if.h>
|
29 | 33 | #include <__type_traits/is_constant_evaluated.h>
|
| 34 | +#include <__type_traits/is_same.h> |
30 | 35 | #include <__type_traits/is_unsigned.h>
|
31 | 36 | #include <__type_traits/void_t.h>
|
32 | 37 | #include <__utility/pair.h>
|
@@ -428,127 +433,6 @@ rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle,
|
428 | 433 | return __r;
|
429 | 434 | }
|
430 | 435 |
|
431 |
| -// equal |
432 |
| - |
433 |
| -template <class _Cp, bool _IC1, bool _IC2> |
434 |
| -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_unaligned( |
435 |
| - __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { |
436 |
| - using _It = __bit_iterator<_Cp, _IC1>; |
437 |
| - using difference_type = typename _It::difference_type; |
438 |
| - using __storage_type = typename _It::__storage_type; |
439 |
| - |
440 |
| - const int __bits_per_word = _It::__bits_per_word; |
441 |
| - difference_type __n = __last1 - __first1; |
442 |
| - if (__n > 0) { |
443 |
| - // do first word |
444 |
| - if (__first1.__ctz_ != 0) { |
445 |
| - unsigned __clz_f = __bits_per_word - __first1.__ctz_; |
446 |
| - difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n); |
447 |
| - __n -= __dn; |
448 |
| - __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); |
449 |
| - __storage_type __b = *__first1.__seg_ & __m; |
450 |
| - unsigned __clz_r = __bits_per_word - __first2.__ctz_; |
451 |
| - __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); |
452 |
| - __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); |
453 |
| - if (__first2.__ctz_ > __first1.__ctz_) { |
454 |
| - if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) |
455 |
| - return false; |
456 |
| - } else { |
457 |
| - if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) |
458 |
| - return false; |
459 |
| - } |
460 |
| - __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; |
461 |
| - __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word); |
462 |
| - __dn -= __ddn; |
463 |
| - if (__dn > 0) { |
464 |
| - __m = ~__storage_type(0) >> (__bits_per_word - __dn); |
465 |
| - if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) |
466 |
| - return false; |
467 |
| - __first2.__ctz_ = static_cast<unsigned>(__dn); |
468 |
| - } |
469 |
| - ++__first1.__seg_; |
470 |
| - // __first1.__ctz_ = 0; |
471 |
| - } |
472 |
| - // __first1.__ctz_ == 0; |
473 |
| - // do middle words |
474 |
| - unsigned __clz_r = __bits_per_word - __first2.__ctz_; |
475 |
| - __storage_type __m = ~__storage_type(0) << __first2.__ctz_; |
476 |
| - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) { |
477 |
| - __storage_type __b = *__first1.__seg_; |
478 |
| - if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) |
479 |
| - return false; |
480 |
| - ++__first2.__seg_; |
481 |
| - if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) |
482 |
| - return false; |
483 |
| - } |
484 |
| - // do last word |
485 |
| - if (__n > 0) { |
486 |
| - __m = ~__storage_type(0) >> (__bits_per_word - __n); |
487 |
| - __storage_type __b = *__first1.__seg_ & __m; |
488 |
| - __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r)); |
489 |
| - __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); |
490 |
| - if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) |
491 |
| - return false; |
492 |
| - __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; |
493 |
| - __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word); |
494 |
| - __n -= __dn; |
495 |
| - if (__n > 0) { |
496 |
| - __m = ~__storage_type(0) >> (__bits_per_word - __n); |
497 |
| - if ((*__first2.__seg_ & __m) != (__b >> __dn)) |
498 |
| - return false; |
499 |
| - } |
500 |
| - } |
501 |
| - } |
502 |
| - return true; |
503 |
| -} |
504 |
| - |
505 |
| -template <class _Cp, bool _IC1, bool _IC2> |
506 |
| -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_aligned( |
507 |
| - __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { |
508 |
| - using _It = __bit_iterator<_Cp, _IC1>; |
509 |
| - using difference_type = typename _It::difference_type; |
510 |
| - using __storage_type = typename _It::__storage_type; |
511 |
| - |
512 |
| - const int __bits_per_word = _It::__bits_per_word; |
513 |
| - difference_type __n = __last1 - __first1; |
514 |
| - if (__n > 0) { |
515 |
| - // do first word |
516 |
| - if (__first1.__ctz_ != 0) { |
517 |
| - unsigned __clz = __bits_per_word - __first1.__ctz_; |
518 |
| - difference_type __dn = std::min(static_cast<difference_type>(__clz), __n); |
519 |
| - __n -= __dn; |
520 |
| - __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); |
521 |
| - if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) |
522 |
| - return false; |
523 |
| - ++__first2.__seg_; |
524 |
| - ++__first1.__seg_; |
525 |
| - // __first1.__ctz_ = 0; |
526 |
| - // __first2.__ctz_ = 0; |
527 |
| - } |
528 |
| - // __first1.__ctz_ == 0; |
529 |
| - // __first2.__ctz_ == 0; |
530 |
| - // do middle words |
531 |
| - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) |
532 |
| - if (*__first2.__seg_ != *__first1.__seg_) |
533 |
| - return false; |
534 |
| - // do last word |
535 |
| - if (__n > 0) { |
536 |
| - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); |
537 |
| - if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) |
538 |
| - return false; |
539 |
| - } |
540 |
| - } |
541 |
| - return true; |
542 |
| -} |
543 |
| - |
544 |
| -template <class _Cp, bool _IC1, bool _IC2> |
545 |
| -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool |
546 |
| -equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { |
547 |
| - if (__first1.__ctz_ == __first2.__ctz_) |
548 |
| - return std::__equal_aligned(__first1, __last1, __first2); |
549 |
| - return std::__equal_unaligned(__first1, __last1, __first2); |
550 |
| -} |
551 |
| - |
552 | 436 | template <class _Cp, bool _IsConst, typename _Cp::__storage_type>
|
553 | 437 | class __bit_iterator {
|
554 | 438 | public:
|
@@ -771,15 +655,36 @@ private:
|
771 | 655 | template <class _Dp>
|
772 | 656 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
|
773 | 657 | rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>);
|
774 |
| - template <class _Dp, bool _IC1, bool _IC2> |
775 |
| - _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool |
776 |
| - __equal_aligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); |
777 |
| - template <class _Dp, bool _IC1, bool _IC2> |
| 658 | + template <class _Dp, bool _IsConst1, bool _IsConst2> |
778 | 659 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
|
779 |
| - __equal_unaligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); |
780 |
| - template <class _Dp, bool _IC1, bool _IC2> |
| 660 | + __equal_aligned(__bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>); |
| 661 | + template <class _Dp, bool _IsConst1, bool _IsConst2> |
781 | 662 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool
|
782 |
| - equal(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); |
| 663 | + __equal_unaligned(__bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>); |
| 664 | + template <class _Dp, |
| 665 | + bool _IsConst1, |
| 666 | + bool _IsConst2, |
| 667 | + class _BinaryPredicate, |
| 668 | + __enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>, int> > |
| 669 | + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool __equal_iter_impl( |
| 670 | + __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>, _BinaryPredicate); |
| 671 | + template <class _Dp, |
| 672 | + bool _IsConst1, |
| 673 | + bool _IsConst2, |
| 674 | + class _Pred, |
| 675 | + class _Proj1, |
| 676 | + class _Proj2, |
| 677 | + __enable_if_t<__desugars_to_v<__equal_tag, _Pred, bool, bool> && __is_identity<_Proj1>::value && |
| 678 | + __is_identity<_Proj2>::value, |
| 679 | + int> > |
| 680 | + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool __equal_impl( |
| 681 | + __bit_iterator<_Dp, _IsConst1> __first1, |
| 682 | + __bit_iterator<_Dp, _IsConst1> __last1, |
| 683 | + __bit_iterator<_Dp, _IsConst2> __first2, |
| 684 | + __bit_iterator<_Dp, _IsConst2>, |
| 685 | + _Pred&, |
| 686 | + _Proj1&, |
| 687 | + _Proj2&); |
783 | 688 | template <bool _ToFind, class _Dp, bool _IC>
|
784 | 689 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, _IC>
|
785 | 690 | __find_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type);
|
|
0 commit comments