|
12 | 12 |
|
13 | 13 | #include <__algorithm/copy_n.h> |
14 | 14 | #include <__algorithm/min.h> |
| 15 | +#include <__algorithm/swap_ranges.h> |
15 | 16 | #include <__bit/countr.h> |
16 | 17 | #include <__compare/ordering.h> |
17 | 18 | #include <__config> |
@@ -437,152 +438,6 @@ inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> move_backward( |
437 | 438 | return std::copy_backward(__first, __last, __result); |
438 | 439 | } |
439 | 440 |
|
440 | | -// swap_ranges |
441 | | - |
442 | | -template <class _Cl, class _Cr> |
443 | | -_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_aligned( |
444 | | - __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) { |
445 | | - using _I1 = __bit_iterator<_Cl, false>; |
446 | | - using difference_type = typename _I1::difference_type; |
447 | | - using __storage_type = typename _I1::__storage_type; |
448 | | - |
449 | | - const int __bits_per_word = _I1::__bits_per_word; |
450 | | - difference_type __n = __last - __first; |
451 | | - if (__n > 0) { |
452 | | - // do first word |
453 | | - if (__first.__ctz_ != 0) { |
454 | | - unsigned __clz = __bits_per_word - __first.__ctz_; |
455 | | - difference_type __dn = std::min(static_cast<difference_type>(__clz), __n); |
456 | | - __n -= __dn; |
457 | | - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); |
458 | | - __storage_type __b1 = *__first.__seg_ & __m; |
459 | | - *__first.__seg_ &= ~__m; |
460 | | - __storage_type __b2 = *__result.__seg_ & __m; |
461 | | - *__result.__seg_ &= ~__m; |
462 | | - *__result.__seg_ |= __b1; |
463 | | - *__first.__seg_ |= __b2; |
464 | | - __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; |
465 | | - __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); |
466 | | - ++__first.__seg_; |
467 | | - // __first.__ctz_ = 0; |
468 | | - } |
469 | | - // __first.__ctz_ == 0; |
470 | | - // do middle words |
471 | | - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) |
472 | | - swap(*__first.__seg_, *__result.__seg_); |
473 | | - // do last word |
474 | | - if (__n > 0) { |
475 | | - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); |
476 | | - __storage_type __b1 = *__first.__seg_ & __m; |
477 | | - *__first.__seg_ &= ~__m; |
478 | | - __storage_type __b2 = *__result.__seg_ & __m; |
479 | | - *__result.__seg_ &= ~__m; |
480 | | - *__result.__seg_ |= __b1; |
481 | | - *__first.__seg_ |= __b2; |
482 | | - __result.__ctz_ = static_cast<unsigned>(__n); |
483 | | - } |
484 | | - } |
485 | | - return __result; |
486 | | -} |
487 | | - |
488 | | -template <class _Cl, class _Cr> |
489 | | -_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_unaligned( |
490 | | - __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) { |
491 | | - using _I1 = __bit_iterator<_Cl, false>; |
492 | | - using difference_type = typename _I1::difference_type; |
493 | | - using __storage_type = typename _I1::__storage_type; |
494 | | - |
495 | | - const int __bits_per_word = _I1::__bits_per_word; |
496 | | - difference_type __n = __last - __first; |
497 | | - if (__n > 0) { |
498 | | - // do first word |
499 | | - if (__first.__ctz_ != 0) { |
500 | | - unsigned __clz_f = __bits_per_word - __first.__ctz_; |
501 | | - difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n); |
502 | | - __n -= __dn; |
503 | | - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); |
504 | | - __storage_type __b1 = *__first.__seg_ & __m; |
505 | | - *__first.__seg_ &= ~__m; |
506 | | - unsigned __clz_r = __bits_per_word - __result.__ctz_; |
507 | | - __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); |
508 | | - __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); |
509 | | - __storage_type __b2 = *__result.__seg_ & __m; |
510 | | - *__result.__seg_ &= ~__m; |
511 | | - if (__result.__ctz_ > __first.__ctz_) { |
512 | | - unsigned __s = __result.__ctz_ - __first.__ctz_; |
513 | | - *__result.__seg_ |= __b1 << __s; |
514 | | - *__first.__seg_ |= __b2 >> __s; |
515 | | - } else { |
516 | | - unsigned __s = __first.__ctz_ - __result.__ctz_; |
517 | | - *__result.__seg_ |= __b1 >> __s; |
518 | | - *__first.__seg_ |= __b2 << __s; |
519 | | - } |
520 | | - __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; |
521 | | - __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); |
522 | | - __dn -= __ddn; |
523 | | - if (__dn > 0) { |
524 | | - __m = ~__storage_type(0) >> (__bits_per_word - __dn); |
525 | | - __b2 = *__result.__seg_ & __m; |
526 | | - *__result.__seg_ &= ~__m; |
527 | | - unsigned __s = __first.__ctz_ + __ddn; |
528 | | - *__result.__seg_ |= __b1 >> __s; |
529 | | - *__first.__seg_ |= __b2 << __s; |
530 | | - __result.__ctz_ = static_cast<unsigned>(__dn); |
531 | | - } |
532 | | - ++__first.__seg_; |
533 | | - // __first.__ctz_ = 0; |
534 | | - } |
535 | | - // __first.__ctz_ == 0; |
536 | | - // do middle words |
537 | | - __storage_type __m = ~__storage_type(0) << __result.__ctz_; |
538 | | - unsigned __clz_r = __bits_per_word - __result.__ctz_; |
539 | | - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) { |
540 | | - __storage_type __b1 = *__first.__seg_; |
541 | | - __storage_type __b2 = *__result.__seg_ & __m; |
542 | | - *__result.__seg_ &= ~__m; |
543 | | - *__result.__seg_ |= __b1 << __result.__ctz_; |
544 | | - *__first.__seg_ = __b2 >> __result.__ctz_; |
545 | | - ++__result.__seg_; |
546 | | - __b2 = *__result.__seg_ & ~__m; |
547 | | - *__result.__seg_ &= __m; |
548 | | - *__result.__seg_ |= __b1 >> __clz_r; |
549 | | - *__first.__seg_ |= __b2 << __clz_r; |
550 | | - } |
551 | | - // do last word |
552 | | - if (__n > 0) { |
553 | | - __m = ~__storage_type(0) >> (__bits_per_word - __n); |
554 | | - __storage_type __b1 = *__first.__seg_ & __m; |
555 | | - *__first.__seg_ &= ~__m; |
556 | | - __storage_type __dn = std::min<__storage_type>(__n, __clz_r); |
557 | | - __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); |
558 | | - __storage_type __b2 = *__result.__seg_ & __m; |
559 | | - *__result.__seg_ &= ~__m; |
560 | | - *__result.__seg_ |= __b1 << __result.__ctz_; |
561 | | - *__first.__seg_ |= __b2 >> __result.__ctz_; |
562 | | - __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; |
563 | | - __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); |
564 | | - __n -= __dn; |
565 | | - if (__n > 0) { |
566 | | - __m = ~__storage_type(0) >> (__bits_per_word - __n); |
567 | | - __b2 = *__result.__seg_ & __m; |
568 | | - *__result.__seg_ &= ~__m; |
569 | | - *__result.__seg_ |= __b1 >> __dn; |
570 | | - *__first.__seg_ |= __b2 << __dn; |
571 | | - __result.__ctz_ = static_cast<unsigned>(__n); |
572 | | - } |
573 | | - } |
574 | | - } |
575 | | - return __result; |
576 | | -} |
577 | | - |
578 | | -template <class _Cl, class _Cr> |
579 | | -inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges( |
580 | | - __bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1, __bit_iterator<_Cr, false> __first2) { |
581 | | - if (__first1.__ctz_ == __first2.__ctz_) |
582 | | - return std::__swap_ranges_aligned(__first1, __last1, __first2); |
583 | | - return std::__swap_ranges_unaligned(__first1, __last1, __first2); |
584 | | -} |
585 | | - |
586 | 441 | // rotate |
587 | 442 |
|
588 | 443 | template <class _Cp> |
@@ -987,14 +842,14 @@ private: |
987 | 842 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> |
988 | 843 | copy_backward(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); |
989 | 844 | template <class _Cl, class _Cr> |
990 | | - friend __bit_iterator<_Cr, false> |
| 845 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Cr, false> |
991 | 846 | __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
992 | 847 | template <class _Cl, class _Cr> |
993 | | - friend __bit_iterator<_Cr, false> |
| 848 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Cr, false> |
994 | 849 | __swap_ranges_unaligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
995 | | - template <class _Cl, class _Cr> |
996 | | - friend __bit_iterator<_Cr, false> |
997 | | - swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
| 850 | + template <class, class _Cl, class _Cr> |
| 851 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend pair<__bit_iterator<_Cl, false>, __bit_iterator<_Cr, false> > |
| 852 | + __swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
998 | 853 | template <class _Dp> |
999 | 854 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> |
1000 | 855 | rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>); |
|
0 commit comments