13
13
#include < __algorithm/for_each_segment.h>
14
14
#include < __algorithm/min.h>
15
15
#include < __config>
16
+ #include < __fwd/bit_reference.h>
16
17
#include < __iterator/iterator_traits.h>
17
18
#include < __iterator/segmented_iterator.h>
19
+ #include < __memory/pointer_traits.h>
18
20
#include < __type_traits/common_type.h>
19
21
#include < __type_traits/enable_if.h>
20
22
#include < __utility/move.h>
@@ -29,9 +31,129 @@ _LIBCPP_PUSH_MACROS
29
31
30
32
_LIBCPP_BEGIN_NAMESPACE_STD
31
33
34
+ template <class _InputIterator , class _OutputIterator >
35
+ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
36
+ copy (_InputIterator __first, _InputIterator __last, _OutputIterator __result);
37
+
32
38
template <class _InIter , class _Sent , class _OutIter >
33
39
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy (_InIter, _Sent, _OutIter);
34
40
41
+ template <class _Cp , bool _IsConst>
42
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false > __copy_aligned (
43
+ __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false > __result) {
44
+ using _In = __bit_iterator<_Cp, _IsConst>;
45
+ using difference_type = typename _In::difference_type;
46
+ using __storage_type = typename _In::__storage_type;
47
+
48
+ const int __bits_per_word = _In::__bits_per_word;
49
+ difference_type __n = __last - __first;
50
+ if (__n > 0 ) {
51
+ // do first word
52
+ if (__first.__ctz_ != 0 ) {
53
+ unsigned __clz = __bits_per_word - __first.__ctz_ ;
54
+ difference_type __dn = std::min (static_cast <difference_type>(__clz), __n);
55
+ __n -= __dn;
56
+ __storage_type __m = (~__storage_type (0 ) << __first.__ctz_ ) & (~__storage_type (0 ) >> (__clz - __dn));
57
+ __storage_type __b = *__first.__seg_ & __m;
58
+ *__result.__seg_ &= ~__m;
59
+ *__result.__seg_ |= __b;
60
+ __result.__seg_ += (__dn + __result.__ctz_ ) / __bits_per_word;
61
+ __result.__ctz_ = static_cast <unsigned >((__dn + __result.__ctz_ ) % __bits_per_word);
62
+ ++__first.__seg_ ;
63
+ // __first.__ctz_ = 0;
64
+ }
65
+ // __first.__ctz_ == 0;
66
+ // do middle words
67
+ __storage_type __nw = __n / __bits_per_word;
68
+ std::copy (std::__to_address (__first.__seg_ ),
69
+ std::__to_address (__first.__seg_ + __nw),
70
+ std::__to_address (__result.__seg_ ));
71
+ __n -= __nw * __bits_per_word;
72
+ __result.__seg_ += __nw;
73
+ // do last word
74
+ if (__n > 0 ) {
75
+ __first.__seg_ += __nw;
76
+ __storage_type __m = ~__storage_type (0 ) >> (__bits_per_word - __n);
77
+ __storage_type __b = *__first.__seg_ & __m;
78
+ *__result.__seg_ &= ~__m;
79
+ *__result.__seg_ |= __b;
80
+ __result.__ctz_ = static_cast <unsigned >(__n);
81
+ }
82
+ }
83
+ return __result;
84
+ }
85
+
86
+ template <class _Cp , bool _IsConst>
87
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false > __copy_unaligned (
88
+ __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false > __result) {
89
+ using _In = __bit_iterator<_Cp, _IsConst>;
90
+ using difference_type = typename _In::difference_type;
91
+ using __storage_type = typename _In::__storage_type;
92
+
93
+ const int __bits_per_word = _In::__bits_per_word;
94
+ difference_type __n = __last - __first;
95
+ if (__n > 0 ) {
96
+ // do first word
97
+ if (__first.__ctz_ != 0 ) {
98
+ unsigned __clz_f = __bits_per_word - __first.__ctz_ ;
99
+ difference_type __dn = std::min (static_cast <difference_type>(__clz_f), __n);
100
+ __n -= __dn;
101
+ __storage_type __m = (~__storage_type (0 ) << __first.__ctz_ ) & (~__storage_type (0 ) >> (__clz_f - __dn));
102
+ __storage_type __b = *__first.__seg_ & __m;
103
+ unsigned __clz_r = __bits_per_word - __result.__ctz_ ;
104
+ __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r);
105
+ __m = (~__storage_type (0 ) << __result.__ctz_ ) & (~__storage_type (0 ) >> (__clz_r - __ddn));
106
+ *__result.__seg_ &= ~__m;
107
+ if (__result.__ctz_ > __first.__ctz_ )
108
+ *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_ );
109
+ else
110
+ *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_ );
111
+ __result.__seg_ += (__ddn + __result.__ctz_ ) / __bits_per_word;
112
+ __result.__ctz_ = static_cast <unsigned >((__ddn + __result.__ctz_ ) % __bits_per_word);
113
+ __dn -= __ddn;
114
+ if (__dn > 0 ) {
115
+ __m = ~__storage_type (0 ) >> (__bits_per_word - __dn);
116
+ *__result.__seg_ &= ~__m;
117
+ *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn);
118
+ __result.__ctz_ = static_cast <unsigned >(__dn);
119
+ }
120
+ ++__first.__seg_ ;
121
+ // __first.__ctz_ = 0;
122
+ }
123
+ // __first.__ctz_ == 0;
124
+ // do middle words
125
+ unsigned __clz_r = __bits_per_word - __result.__ctz_ ;
126
+ __storage_type __m = ~__storage_type (0 ) << __result.__ctz_ ;
127
+ for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_ ) {
128
+ __storage_type __b = *__first.__seg_ ;
129
+ *__result.__seg_ &= ~__m;
130
+ *__result.__seg_ |= __b << __result.__ctz_ ;
131
+ ++__result.__seg_ ;
132
+ *__result.__seg_ &= __m;
133
+ *__result.__seg_ |= __b >> __clz_r;
134
+ }
135
+ // do last word
136
+ if (__n > 0 ) {
137
+ __m = ~__storage_type (0 ) >> (__bits_per_word - __n);
138
+ __storage_type __b = *__first.__seg_ & __m;
139
+ __storage_type __dn = std::min (__n, static_cast <difference_type>(__clz_r));
140
+ __m = (~__storage_type (0 ) << __result.__ctz_ ) & (~__storage_type (0 ) >> (__clz_r - __dn));
141
+ *__result.__seg_ &= ~__m;
142
+ *__result.__seg_ |= __b << __result.__ctz_ ;
143
+ __result.__seg_ += (__dn + __result.__ctz_ ) / __bits_per_word;
144
+ __result.__ctz_ = static_cast <unsigned >((__dn + __result.__ctz_ ) % __bits_per_word);
145
+ __n -= __dn;
146
+ if (__n > 0 ) {
147
+ __m = ~__storage_type (0 ) >> (__bits_per_word - __n);
148
+ *__result.__seg_ &= ~__m;
149
+ *__result.__seg_ |= __b >> __dn;
150
+ __result.__ctz_ = static_cast <unsigned >(__n);
151
+ }
152
+ }
153
+ }
154
+ return __result;
155
+ }
156
+
35
157
struct __copy_impl {
36
158
template <class _InIter , class _Sent , class _OutIter >
37
159
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
@@ -95,6 +217,16 @@ struct __copy_impl {
95
217
}
96
218
}
97
219
220
+ template <class _Cp , bool _IsConst>
221
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<__bit_iterator<_Cp, _IsConst>, __bit_iterator<_Cp, false > >
222
+ operator ()(__bit_iterator<_Cp, _IsConst> __first,
223
+ __bit_iterator<_Cp, _IsConst> __last,
224
+ __bit_iterator<_Cp, false > __result) {
225
+ if (__first.__ctz_ == __result.__ctz_ )
226
+ return std::make_pair (__last, std::__copy_aligned (__first, __last, __result));
227
+ return std::make_pair (__last, std::__copy_unaligned (__first, __last, __result));
228
+ }
229
+
98
230
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
99
231
template <class _In , class _Out , __enable_if_t <__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int > = 0 >
100
232
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
@@ -110,7 +242,7 @@ __copy(_InIter __first, _Sent __last, _OutIter __result) {
110
242
}
111
243
112
244
template <class _InputIterator , class _OutputIterator >
113
- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
245
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
114
246
copy (_InputIterator __first, _InputIterator __last, _OutputIterator __result) {
115
247
return std::__copy (__first, __last, __result).second ;
116
248
}
0 commit comments