|
14 | 14 | #include <__cxx03/__algorithm/iterator_operations.h> |
15 | 15 | #include <__cxx03/__algorithm/min.h> |
16 | 16 | #include <__cxx03/__config> |
| 17 | +#include <__cxx03/__fwd/bit_reference.h> |
| 18 | +#include <__cxx03/__iterator/distance.h> |
17 | 19 | #include <__cxx03/__iterator/segmented_iterator.h> |
18 | 20 | #include <__cxx03/__type_traits/common_type.h> |
19 | 21 | #include <__cxx03/__utility/move.h> |
@@ -95,6 +97,54 @@ struct __copy_impl { |
95 | 97 | } |
96 | 98 | } |
97 | 99 |
|
| 100 | + template <class _InIter, class _Cp, __enable_if_t<__has_forward_iterator_category<_InIter>::value, int> = 0> |
| 101 | + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, __bit_iterator<_Cp, false>> |
| 102 | + operator()(_InIter __first, _InIter __last, __bit_iterator<_Cp, false> __result) { |
| 103 | + using _It = __bit_iterator<_Cp, false>; |
| 104 | + using __storage_type = typename _It::__storage_type; |
| 105 | + __storage_type __n = static_cast<__storage_type>(std::distance(__first, __last)); |
| 106 | + const unsigned __bits_per_word = _It::__bits_per_word; |
| 107 | + |
| 108 | + if (__n) { |
| 109 | + // do first partial word, if present |
| 110 | + if (__result.__ctz_ != 0) { |
| 111 | + __storage_type __clz = static_cast<__storage_type>(__bits_per_word - __result.__ctz_); |
| 112 | + __storage_type __dn = std::min(__clz, __n); |
| 113 | + __storage_type __w = *__result.__seg_; |
| 114 | + __storage_type __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); |
| 115 | + __w &= ~__m; |
| 116 | + for (__storage_type __i = 0; __i < __dn; ++__i, ++__first) |
| 117 | + __w |= static_cast<__storage_type>(*__first) << __result.__ctz_++; |
| 118 | + *__result.__seg_ = __w; |
| 119 | + if (__result.__ctz_ == __bits_per_word) { |
| 120 | + __result.__ctz_ = 0; |
| 121 | + ++__result.__seg_; |
| 122 | + } |
| 123 | + __n -= __dn; |
| 124 | + } |
| 125 | + } |
| 126 | + // do middle whole words, if present |
| 127 | + __storage_type __nw = __n / __bits_per_word; |
| 128 | + __n -= __nw * __bits_per_word; |
| 129 | + for (; __nw; --__nw) { |
| 130 | + __storage_type __w = 0; |
| 131 | + for (__storage_type __i = 0; __i < __bits_per_word; ++__i, ++__first) |
| 132 | + __w |= static_cast<__storage_type>(*__first) << __i; |
| 133 | + *__result.__seg_++ = __w; |
| 134 | + } |
| 135 | + // do last partial word, if present |
| 136 | + if (__n) { |
| 137 | + __storage_type __w = 0; |
| 138 | + for (__storage_type __i = 0; __i < __n; ++__i, ++__first) |
| 139 | + __w |= static_cast<__storage_type>(*__first) << __i; |
| 140 | + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); |
| 141 | + *__result.__seg_ &= ~__m; |
| 142 | + *__result.__seg_ |= __w; |
| 143 | + __result.__ctz_ = __n; |
| 144 | + } |
| 145 | + return std::make_pair(std::move(__first), std::move(__result)); |
| 146 | + } |
| 147 | + |
98 | 148 | // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. |
99 | 149 | template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0> |
100 | 150 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> |
|
0 commit comments