|
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>
|
|
24 | 25 | #include <__type_traits/conditional.h>
|
25 | 26 | #include <__type_traits/is_constant_evaluated.h>
|
26 | 27 | #include <__type_traits/void_t.h>
|
| 28 | +#include <__utility/pair.h> |
27 | 29 | #include <__utility/swap.h>
|
28 | 30 |
|
29 | 31 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
@@ -451,152 +453,6 @@ inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> move_backward(
|
451 | 453 | return std::copy_backward(__first, __last, __result);
|
452 | 454 | }
|
453 | 455 |
|
454 |
| -// swap_ranges |
455 |
| - |
456 |
| -template <class _Cl, class _Cr> |
457 |
| -_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_aligned( |
458 |
| - __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) { |
459 |
| - using _I1 = __bit_iterator<_Cl, false>; |
460 |
| - using difference_type = typename _I1::difference_type; |
461 |
| - using __storage_type = typename _I1::__storage_type; |
462 |
| - |
463 |
| - const int __bits_per_word = _I1::__bits_per_word; |
464 |
| - difference_type __n = __last - __first; |
465 |
| - if (__n > 0) { |
466 |
| - // do first word |
467 |
| - if (__first.__ctz_ != 0) { |
468 |
| - unsigned __clz = __bits_per_word - __first.__ctz_; |
469 |
| - difference_type __dn = std::min(static_cast<difference_type>(__clz), __n); |
470 |
| - __n -= __dn; |
471 |
| - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); |
472 |
| - __storage_type __b1 = *__first.__seg_ & __m; |
473 |
| - *__first.__seg_ &= ~__m; |
474 |
| - __storage_type __b2 = *__result.__seg_ & __m; |
475 |
| - *__result.__seg_ &= ~__m; |
476 |
| - *__result.__seg_ |= __b1; |
477 |
| - *__first.__seg_ |= __b2; |
478 |
| - __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; |
479 |
| - __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); |
480 |
| - ++__first.__seg_; |
481 |
| - // __first.__ctz_ = 0; |
482 |
| - } |
483 |
| - // __first.__ctz_ == 0; |
484 |
| - // do middle words |
485 |
| - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) |
486 |
| - swap(*__first.__seg_, *__result.__seg_); |
487 |
| - // do last word |
488 |
| - if (__n > 0) { |
489 |
| - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); |
490 |
| - __storage_type __b1 = *__first.__seg_ & __m; |
491 |
| - *__first.__seg_ &= ~__m; |
492 |
| - __storage_type __b2 = *__result.__seg_ & __m; |
493 |
| - *__result.__seg_ &= ~__m; |
494 |
| - *__result.__seg_ |= __b1; |
495 |
| - *__first.__seg_ |= __b2; |
496 |
| - __result.__ctz_ = static_cast<unsigned>(__n); |
497 |
| - } |
498 |
| - } |
499 |
| - return __result; |
500 |
| -} |
501 |
| - |
502 |
| -template <class _Cl, class _Cr> |
503 |
| -_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_unaligned( |
504 |
| - __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) { |
505 |
| - using _I1 = __bit_iterator<_Cl, false>; |
506 |
| - using difference_type = typename _I1::difference_type; |
507 |
| - using __storage_type = typename _I1::__storage_type; |
508 |
| - |
509 |
| - const int __bits_per_word = _I1::__bits_per_word; |
510 |
| - difference_type __n = __last - __first; |
511 |
| - if (__n > 0) { |
512 |
| - // do first word |
513 |
| - if (__first.__ctz_ != 0) { |
514 |
| - unsigned __clz_f = __bits_per_word - __first.__ctz_; |
515 |
| - difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n); |
516 |
| - __n -= __dn; |
517 |
| - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); |
518 |
| - __storage_type __b1 = *__first.__seg_ & __m; |
519 |
| - *__first.__seg_ &= ~__m; |
520 |
| - unsigned __clz_r = __bits_per_word - __result.__ctz_; |
521 |
| - __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); |
522 |
| - __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); |
523 |
| - __storage_type __b2 = *__result.__seg_ & __m; |
524 |
| - *__result.__seg_ &= ~__m; |
525 |
| - if (__result.__ctz_ > __first.__ctz_) { |
526 |
| - unsigned __s = __result.__ctz_ - __first.__ctz_; |
527 |
| - *__result.__seg_ |= __b1 << __s; |
528 |
| - *__first.__seg_ |= __b2 >> __s; |
529 |
| - } else { |
530 |
| - unsigned __s = __first.__ctz_ - __result.__ctz_; |
531 |
| - *__result.__seg_ |= __b1 >> __s; |
532 |
| - *__first.__seg_ |= __b2 << __s; |
533 |
| - } |
534 |
| - __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; |
535 |
| - __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); |
536 |
| - __dn -= __ddn; |
537 |
| - if (__dn > 0) { |
538 |
| - __m = ~__storage_type(0) >> (__bits_per_word - __dn); |
539 |
| - __b2 = *__result.__seg_ & __m; |
540 |
| - *__result.__seg_ &= ~__m; |
541 |
| - unsigned __s = __first.__ctz_ + __ddn; |
542 |
| - *__result.__seg_ |= __b1 >> __s; |
543 |
| - *__first.__seg_ |= __b2 << __s; |
544 |
| - __result.__ctz_ = static_cast<unsigned>(__dn); |
545 |
| - } |
546 |
| - ++__first.__seg_; |
547 |
| - // __first.__ctz_ = 0; |
548 |
| - } |
549 |
| - // __first.__ctz_ == 0; |
550 |
| - // do middle words |
551 |
| - __storage_type __m = ~__storage_type(0) << __result.__ctz_; |
552 |
| - unsigned __clz_r = __bits_per_word - __result.__ctz_; |
553 |
| - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) { |
554 |
| - __storage_type __b1 = *__first.__seg_; |
555 |
| - __storage_type __b2 = *__result.__seg_ & __m; |
556 |
| - *__result.__seg_ &= ~__m; |
557 |
| - *__result.__seg_ |= __b1 << __result.__ctz_; |
558 |
| - *__first.__seg_ = __b2 >> __result.__ctz_; |
559 |
| - ++__result.__seg_; |
560 |
| - __b2 = *__result.__seg_ & ~__m; |
561 |
| - *__result.__seg_ &= __m; |
562 |
| - *__result.__seg_ |= __b1 >> __clz_r; |
563 |
| - *__first.__seg_ |= __b2 << __clz_r; |
564 |
| - } |
565 |
| - // do last word |
566 |
| - if (__n > 0) { |
567 |
| - __m = ~__storage_type(0) >> (__bits_per_word - __n); |
568 |
| - __storage_type __b1 = *__first.__seg_ & __m; |
569 |
| - *__first.__seg_ &= ~__m; |
570 |
| - __storage_type __dn = std::min<__storage_type>(__n, __clz_r); |
571 |
| - __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); |
572 |
| - __storage_type __b2 = *__result.__seg_ & __m; |
573 |
| - *__result.__seg_ &= ~__m; |
574 |
| - *__result.__seg_ |= __b1 << __result.__ctz_; |
575 |
| - *__first.__seg_ |= __b2 >> __result.__ctz_; |
576 |
| - __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; |
577 |
| - __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); |
578 |
| - __n -= __dn; |
579 |
| - if (__n > 0) { |
580 |
| - __m = ~__storage_type(0) >> (__bits_per_word - __n); |
581 |
| - __b2 = *__result.__seg_ & __m; |
582 |
| - *__result.__seg_ &= ~__m; |
583 |
| - *__result.__seg_ |= __b1 >> __dn; |
584 |
| - *__first.__seg_ |= __b2 << __dn; |
585 |
| - __result.__ctz_ = static_cast<unsigned>(__n); |
586 |
| - } |
587 |
| - } |
588 |
| - } |
589 |
| - return __result; |
590 |
| -} |
591 |
| - |
592 |
| -template <class _Cl, class _Cr> |
593 |
| -inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges( |
594 |
| - __bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1, __bit_iterator<_Cr, false> __first2) { |
595 |
| - if (__first1.__ctz_ == __first2.__ctz_) |
596 |
| - return std::__swap_ranges_aligned(__first1, __last1, __first2); |
597 |
| - return std::__swap_ranges_unaligned(__first1, __last1, __first2); |
598 |
| -} |
599 |
| - |
600 | 456 | // rotate
|
601 | 457 |
|
602 | 458 | template <class _Cp>
|
@@ -1001,14 +857,14 @@ private:
|
1001 | 857 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
|
1002 | 858 | copy_backward(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
|
1003 | 859 | template <class _Cl, class _Cr>
|
1004 |
| - friend __bit_iterator<_Cr, false> |
| 860 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Cr, false> |
1005 | 861 | __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
|
1006 | 862 | template <class _Cl, class _Cr>
|
1007 |
| - friend __bit_iterator<_Cr, false> |
| 863 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Cr, false> |
1008 | 864 | __swap_ranges_unaligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
|
1009 |
| - template <class _Cl, class _Cr> |
1010 |
| - friend __bit_iterator<_Cr, false> |
1011 |
| - swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
| 865 | + template <class, class _Cl, class _Cr> |
| 866 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend pair<__bit_iterator<_Cl, false>, __bit_iterator<_Cr, false> > |
| 867 | + __swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
1012 | 868 | template <class _Dp>
|
1013 | 869 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false>
|
1014 | 870 | rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>);
|
|
0 commit comments