1010#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H
1111
1212#include < __algorithm/copy_move_common.h>
13+ #include < __algorithm/copy_n.h>
1314#include < __algorithm/iterator_operations.h>
1415#include < __algorithm/min.h>
1516#include < __config>
17+ #include < __fwd/bit_reference.h>
1618#include < __iterator/iterator_traits.h>
1719#include < __iterator/segmented_iterator.h>
20+ #include < __memory/pointer_traits.h>
1821#include < __type_traits/common_type.h>
1922#include < __type_traits/enable_if.h>
2023#include < __type_traits/is_constructible.h>
@@ -34,6 +37,124 @@ template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
3437_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
3538__copy_backward (_InIter __first, _Sent __last, _OutIter __result);
3639
40+ template <class _Cp , bool _IsConst>
41+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false > __copy_backward_aligned (
42+ __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false > __result) {
43+ using _In = __bit_iterator<_Cp, _IsConst>;
44+ using difference_type = typename _In::difference_type;
45+ using __storage_type = typename _In::__storage_type;
46+
47+ const int __bits_per_word = _In::__bits_per_word;
48+ difference_type __n = __last - __first;
49+ if (__n > 0 ) {
50+ // do first word
51+ if (__last.__ctz_ != 0 ) {
52+ difference_type __dn = std::min (static_cast <difference_type>(__last.__ctz_ ), __n);
53+ __n -= __dn;
54+ unsigned __clz = __bits_per_word - __last.__ctz_ ;
55+ __storage_type __m = (~__storage_type (0 ) << (__last.__ctz_ - __dn)) & (~__storage_type (0 ) >> __clz);
56+ __storage_type __b = *__last.__seg_ & __m;
57+ *__result.__seg_ &= ~__m;
58+ *__result.__seg_ |= __b;
59+ __result.__ctz_ = static_cast <unsigned >(((-__dn & (__bits_per_word - 1 )) + __result.__ctz_ ) % __bits_per_word);
60+ // __last.__ctz_ = 0
61+ }
62+ // __last.__ctz_ == 0 || __n == 0
63+ // __result.__ctz_ == 0 || __n == 0
64+ // do middle words
65+ __storage_type __nw = __n / __bits_per_word;
66+ __result.__seg_ -= __nw;
67+ __last.__seg_ -= __nw;
68+ std::copy_n (std::__to_address (__last.__seg_ ), __nw, std::__to_address (__result.__seg_ ));
69+ __n -= __nw * __bits_per_word;
70+ // do last word
71+ if (__n > 0 ) {
72+ __storage_type __m = ~__storage_type (0 ) << (__bits_per_word - __n);
73+ __storage_type __b = *--__last.__seg_ & __m;
74+ *--__result.__seg_ &= ~__m;
75+ *__result.__seg_ |= __b;
76+ __result.__ctz_ = static_cast <unsigned >(-__n & (__bits_per_word - 1 ));
77+ }
78+ }
79+ return __result;
80+ }
81+
82+ template <class _Cp , bool _IsConst>
83+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false > __copy_backward_unaligned (
84+ __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false > __result) {
85+ using _In = __bit_iterator<_Cp, _IsConst>;
86+ using difference_type = typename _In::difference_type;
87+ using __storage_type = typename _In::__storage_type;
88+
89+ const int __bits_per_word = _In::__bits_per_word;
90+ difference_type __n = __last - __first;
91+ if (__n > 0 ) {
92+ // do first word
93+ if (__last.__ctz_ != 0 ) {
94+ difference_type __dn = std::min (static_cast <difference_type>(__last.__ctz_ ), __n);
95+ __n -= __dn;
96+ unsigned __clz_l = __bits_per_word - __last.__ctz_ ;
97+ __storage_type __m = (~__storage_type (0 ) << (__last.__ctz_ - __dn)) & (~__storage_type (0 ) >> __clz_l);
98+ __storage_type __b = *__last.__seg_ & __m;
99+ unsigned __clz_r = __bits_per_word - __result.__ctz_ ;
100+ __storage_type __ddn = std::min (__dn, static_cast <difference_type>(__result.__ctz_ ));
101+ if (__ddn > 0 ) {
102+ __m = (~__storage_type (0 ) << (__result.__ctz_ - __ddn)) & (~__storage_type (0 ) >> __clz_r);
103+ *__result.__seg_ &= ~__m;
104+ if (__result.__ctz_ > __last.__ctz_ )
105+ *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_ );
106+ else
107+ *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_ );
108+ __result.__ctz_ = static_cast <unsigned >(((-__ddn & (__bits_per_word - 1 )) + __result.__ctz_ ) % __bits_per_word);
109+ __dn -= __ddn;
110+ }
111+ if (__dn > 0 ) {
112+ // __result.__ctz_ == 0
113+ --__result.__seg_ ;
114+ __result.__ctz_ = static_cast <unsigned >(-__dn & (__bits_per_word - 1 ));
115+ __m = ~__storage_type (0 ) << __result.__ctz_ ;
116+ *__result.__seg_ &= ~__m;
117+ __last.__ctz_ -= __dn + __ddn;
118+ *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_ );
119+ }
120+ // __last.__ctz_ = 0
121+ }
122+ // __last.__ctz_ == 0 || __n == 0
123+ // __result.__ctz_ != 0 || __n == 0
124+ // do middle words
125+ unsigned __clz_r = __bits_per_word - __result.__ctz_ ;
126+ __storage_type __m = ~__storage_type (0 ) >> __clz_r;
127+ for (; __n >= __bits_per_word; __n -= __bits_per_word) {
128+ __storage_type __b = *--__last.__seg_ ;
129+ *__result.__seg_ &= ~__m;
130+ *__result.__seg_ |= __b >> __clz_r;
131+ *--__result.__seg_ &= __m;
132+ *__result.__seg_ |= __b << __result.__ctz_ ;
133+ }
134+ // do last word
135+ if (__n > 0 ) {
136+ __m = ~__storage_type (0 ) << (__bits_per_word - __n);
137+ __storage_type __b = *--__last.__seg_ & __m;
138+ __clz_r = __bits_per_word - __result.__ctz_ ;
139+ __storage_type __dn = std::min (__n, static_cast <difference_type>(__result.__ctz_ ));
140+ __m = (~__storage_type (0 ) << (__result.__ctz_ - __dn)) & (~__storage_type (0 ) >> __clz_r);
141+ *__result.__seg_ &= ~__m;
142+ *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_ );
143+ __result.__ctz_ = static_cast <unsigned >(((-__dn & (__bits_per_word - 1 )) + __result.__ctz_ ) % __bits_per_word);
144+ __n -= __dn;
145+ if (__n > 0 ) {
146+ // __result.__ctz_ == 0
147+ --__result.__seg_ ;
148+ __result.__ctz_ = static_cast <unsigned >(-__n & (__bits_per_word - 1 ));
149+ __m = ~__storage_type (0 ) << __result.__ctz_ ;
150+ *__result.__seg_ &= ~__m;
151+ *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn));
152+ }
153+ }
154+ }
155+ return __result;
156+ }
157+
37158template <class _AlgPolicy >
38159struct __copy_backward_impl {
39160 template <class _InIter , class _Sent , class _OutIter >
@@ -107,6 +228,16 @@ struct __copy_backward_impl {
107228 }
108229 }
109230
231+ template <class _Cp , bool _IsConst>
232+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, false > >
233+ operator ()(__bit_iterator<_Cp, _IsConst> __first,
234+ __bit_iterator<_Cp, _IsConst> __last,
235+ __bit_iterator<_Cp, false > __result) {
236+ if (__last.__ctz_ == __result.__ctz_ )
237+ return std::make_pair (__last, std::__copy_backward_aligned (__first, __last, __result));
238+ return std::make_pair (__last, std::__copy_backward_unaligned (__first, __last, __result));
239+ }
240+
110241 // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
111242 template <class _In , class _Out , __enable_if_t <__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int > = 0 >
112243 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
0 commit comments