|
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> |
|
25 | 27 | #include <__memory/construct_at.h> |
26 | 28 | #include <__memory/pointer_traits.h> |
27 | 29 | #include <__type_traits/conditional.h> |
| 30 | +#include <__type_traits/desugars_to.h> |
28 | 31 | #include <__type_traits/enable_if.h> |
29 | 32 | #include <__type_traits/is_constant_evaluated.h> |
| 33 | +#include <__type_traits/is_same.h> |
30 | 34 | #include <__type_traits/is_unsigned.h> |
31 | 35 | #include <__type_traits/void_t.h> |
32 | 36 | #include <__utility/pair.h> |
@@ -444,127 +448,6 @@ rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, |
444 | 448 | return __r; |
445 | 449 | } |
446 | 450 |
|
447 | | -// equal |
448 | | - |
449 | | -template <class _Cp, bool _IC1, bool _IC2> |
450 | | -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_unaligned( |
451 | | - __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { |
452 | | - using _It = __bit_iterator<_Cp, _IC1>; |
453 | | - using difference_type = typename _It::difference_type; |
454 | | - using __storage_type = typename _It::__storage_type; |
455 | | - |
456 | | - const int __bits_per_word = _It::__bits_per_word; |
457 | | - difference_type __n = __last1 - __first1; |
458 | | - if (__n > 0) { |
459 | | - // do first word |
460 | | - if (__first1.__ctz_ != 0) { |
461 | | - unsigned __clz_f = __bits_per_word - __first1.__ctz_; |
462 | | - difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n); |
463 | | - __n -= __dn; |
464 | | - __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); |
465 | | - __storage_type __b = *__first1.__seg_ & __m; |
466 | | - unsigned __clz_r = __bits_per_word - __first2.__ctz_; |
467 | | - __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); |
468 | | - __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); |
469 | | - if (__first2.__ctz_ > __first1.__ctz_) { |
470 | | - if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) |
471 | | - return false; |
472 | | - } else { |
473 | | - if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) |
474 | | - return false; |
475 | | - } |
476 | | - __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; |
477 | | - __first2.__ctz_ = static_cast<unsigned>((__ddn + __first2.__ctz_) % __bits_per_word); |
478 | | - __dn -= __ddn; |
479 | | - if (__dn > 0) { |
480 | | - __m = ~__storage_type(0) >> (__bits_per_word - __dn); |
481 | | - if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) |
482 | | - return false; |
483 | | - __first2.__ctz_ = static_cast<unsigned>(__dn); |
484 | | - } |
485 | | - ++__first1.__seg_; |
486 | | - // __first1.__ctz_ = 0; |
487 | | - } |
488 | | - // __first1.__ctz_ == 0; |
489 | | - // do middle words |
490 | | - unsigned __clz_r = __bits_per_word - __first2.__ctz_; |
491 | | - __storage_type __m = ~__storage_type(0) << __first2.__ctz_; |
492 | | - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) { |
493 | | - __storage_type __b = *__first1.__seg_; |
494 | | - if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) |
495 | | - return false; |
496 | | - ++__first2.__seg_; |
497 | | - if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) |
498 | | - return false; |
499 | | - } |
500 | | - // do last word |
501 | | - if (__n > 0) { |
502 | | - __m = ~__storage_type(0) >> (__bits_per_word - __n); |
503 | | - __storage_type __b = *__first1.__seg_ & __m; |
504 | | - __storage_type __dn = std::min(__n, static_cast<difference_type>(__clz_r)); |
505 | | - __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); |
506 | | - if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) |
507 | | - return false; |
508 | | - __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; |
509 | | - __first2.__ctz_ = static_cast<unsigned>((__dn + __first2.__ctz_) % __bits_per_word); |
510 | | - __n -= __dn; |
511 | | - if (__n > 0) { |
512 | | - __m = ~__storage_type(0) >> (__bits_per_word - __n); |
513 | | - if ((*__first2.__seg_ & __m) != (__b >> __dn)) |
514 | | - return false; |
515 | | - } |
516 | | - } |
517 | | - } |
518 | | - return true; |
519 | | -} |
520 | | - |
521 | | -template <class _Cp, bool _IC1, bool _IC2> |
522 | | -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_aligned( |
523 | | - __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { |
524 | | - using _It = __bit_iterator<_Cp, _IC1>; |
525 | | - using difference_type = typename _It::difference_type; |
526 | | - using __storage_type = typename _It::__storage_type; |
527 | | - |
528 | | - const int __bits_per_word = _It::__bits_per_word; |
529 | | - difference_type __n = __last1 - __first1; |
530 | | - if (__n > 0) { |
531 | | - // do first word |
532 | | - if (__first1.__ctz_ != 0) { |
533 | | - unsigned __clz = __bits_per_word - __first1.__ctz_; |
534 | | - difference_type __dn = std::min(static_cast<difference_type>(__clz), __n); |
535 | | - __n -= __dn; |
536 | | - __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); |
537 | | - if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) |
538 | | - return false; |
539 | | - ++__first2.__seg_; |
540 | | - ++__first1.__seg_; |
541 | | - // __first1.__ctz_ = 0; |
542 | | - // __first2.__ctz_ = 0; |
543 | | - } |
544 | | - // __first1.__ctz_ == 0; |
545 | | - // __first2.__ctz_ == 0; |
546 | | - // do middle words |
547 | | - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) |
548 | | - if (*__first2.__seg_ != *__first1.__seg_) |
549 | | - return false; |
550 | | - // do last word |
551 | | - if (__n > 0) { |
552 | | - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); |
553 | | - if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) |
554 | | - return false; |
555 | | - } |
556 | | - } |
557 | | - return true; |
558 | | -} |
559 | | - |
560 | | -template <class _Cp, bool _IC1, bool _IC2> |
561 | | -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool |
562 | | -equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { |
563 | | - if (__first1.__ctz_ == __first2.__ctz_) |
564 | | - return std::__equal_aligned(__first1, __last1, __first2); |
565 | | - return std::__equal_unaligned(__first1, __last1, __first2); |
566 | | -} |
567 | | - |
568 | 451 | template <class _Cp, bool _IsConst, typename _Cp::__storage_type> |
569 | 452 | class __bit_iterator { |
570 | 453 | public: |
@@ -787,15 +670,36 @@ private: |
787 | 670 | template <class _Dp> |
788 | 671 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> |
789 | 672 | rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>); |
790 | | - template <class _Dp, bool _IC1, bool _IC2> |
791 | | - _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool |
792 | | - __equal_aligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); |
793 | | - template <class _Dp, bool _IC1, bool _IC2> |
| 673 | + template <class _Dp, bool _IsConst1, bool _IsConst2> |
794 | 674 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool |
795 | | - __equal_unaligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); |
796 | | - template <class _Dp, bool _IC1, bool _IC2> |
| 675 | + __equal_aligned(__bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>); |
| 676 | + template <class _Dp, bool _IsConst1, bool _IsConst2> |
797 | 677 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool |
798 | | - equal(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); |
| 678 | + __equal_unaligned(__bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>); |
| 679 | + template <class _Dp, |
| 680 | + bool _IsConst1, |
| 681 | + bool _IsConst2, |
| 682 | + class _BinaryPredicate, |
| 683 | + __enable_if_t<__desugars_to_v<__equal_tag, _BinaryPredicate, bool, bool>, int> > |
| 684 | + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool __equal_iter_impl( |
| 685 | + __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst1>, __bit_iterator<_Dp, _IsConst2>, _BinaryPredicate); |
| 686 | + template <class _Dp, |
| 687 | + bool _IsConst1, |
| 688 | + bool _IsConst2, |
| 689 | + class _Pred, |
| 690 | + class _Proj1, |
| 691 | + class _Proj2, |
| 692 | + __enable_if_t<__desugars_to_v<__equal_tag, _Pred, bool, bool> && __is_identity<_Proj1>::value && |
| 693 | + __is_identity<_Proj2>::value, |
| 694 | + int> > |
| 695 | + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool __equal_impl( |
| 696 | + __bit_iterator<_Dp, _IsConst1> __first1, |
| 697 | + __bit_iterator<_Dp, _IsConst1> __last1, |
| 698 | + __bit_iterator<_Dp, _IsConst2> __first2, |
| 699 | + __bit_iterator<_Dp, _IsConst2>, |
| 700 | + _Pred&, |
| 701 | + _Proj1&, |
| 702 | + _Proj2&); |
799 | 703 | template <bool _ToFind, class _Dp, bool _IC> |
800 | 704 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, _IC> |
801 | 705 | __find_bool(__bit_iterator<_Dp, _IC>, typename __size_difference_type_traits<_Dp>::size_type); |
|
0 commit comments