10
10
#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H
11
11
12
12
#include < __algorithm/copy_move_common.h>
13
+ #include < __algorithm/copy_n.h>
13
14
#include < __algorithm/iterator_operations.h>
14
15
#include < __algorithm/min.h>
15
16
#include < __config>
17
+ #include < __fwd/bit_reference.h>
16
18
#include < __iterator/iterator_traits.h>
17
19
#include < __iterator/segmented_iterator.h>
20
+ #include < __memory/pointer_traits.h>
18
21
#include < __type_traits/common_type.h>
19
22
#include < __type_traits/enable_if.h>
20
23
#include < __type_traits/is_constructible.h>
@@ -34,6 +37,124 @@ template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter>
34
37
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter>
35
38
__copy_backward (_InIter __first, _Sent __last, _OutIter __result);
36
39
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
+
37
158
template <class _AlgPolicy >
38
159
struct __copy_backward_impl {
39
160
template <class _InIter , class _Sent , class _OutIter >
@@ -107,6 +228,16 @@ struct __copy_backward_impl {
107
228
}
108
229
}
109
230
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
+
110
241
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
111
242
template <class _In , class _Out , __enable_if_t <__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int > = 0 >
112
243
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
0 commit comments