|
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> |
| 19 | +#include <__cxx03/__iterator/iterator_traits.h> |
17 | 20 | #include <__cxx03/__iterator/segmented_iterator.h> |
18 | 21 | #include <__cxx03/__type_traits/common_type.h> |
19 | 22 | #include <__cxx03/__utility/move.h> |
@@ -103,6 +106,60 @@ struct __copy_impl { |
103 | 106 | } |
104 | 107 | }; |
105 | 108 |
|
| 109 | +template <class _InIter, class _Sent, class _Cp> |
| 110 | +_LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI pair<_InIter, __bit_iterator<_Cp, false>> |
| 111 | +__copy_bool(_InIter __first, _Sent __last, __bit_iterator<_Cp, false> __result) { |
| 112 | + using _It = __bit_iterator<_Cp, false>; |
| 113 | + using __storage_type = typename _It::__storage_type; |
| 114 | + __storage_type __n = static_cast<__storage_type>(std::distance(__first, __last)); |
| 115 | + const unsigned __bits_per_word = _It::__bits_per_word; |
| 116 | + |
| 117 | + if (__n) { |
| 118 | + // do first partial word, if present |
| 119 | + if (__result.__ctz_ != 0) { |
| 120 | + __storage_type __clz = static_cast<__storage_type>(__bits_per_word - __result.__ctz_); |
| 121 | + __storage_type __dn = std::min(__clz, __n); |
| 122 | + __storage_type __w = *__result.__seg_; |
| 123 | + __storage_type __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); |
| 124 | + __w &= ~__m; |
| 125 | + for (__storage_type __i = 0; __i < __dn; ++__i, ++__first) |
| 126 | + __w |= static_cast<__storage_type>(*__first) << __result.__ctz_++; |
| 127 | + *__result.__seg_ = __w; |
| 128 | + if (__result.__ctz_ == __bits_per_word) { |
| 129 | + __result.__ctz_ = 0; |
| 130 | + ++__result.__seg_; |
| 131 | + } |
| 132 | + __n -= __dn; |
| 133 | + } |
| 134 | + } |
| 135 | + // do middle whole words, if present |
| 136 | + __storage_type __nw = __n / __bits_per_word; |
| 137 | + __n -= __nw * __bits_per_word; |
| 138 | + for (; __nw; --__nw) { |
| 139 | + __storage_type __w = 0; |
| 140 | + for (__storage_type __i = 0; __i < __bits_per_word; ++__i, ++__first) |
| 141 | + __w |= static_cast<__storage_type>(*__first) << __i; |
| 142 | + *__result.__seg_++ = __w; |
| 143 | + } |
| 144 | + // do last partial word, if present |
| 145 | + if (__n) { |
| 146 | + __storage_type __w = 0; |
| 147 | + for (__storage_type __i = 0; __i < __n; ++__i, ++__first) |
| 148 | + __w |= static_cast<__storage_type>(*__first) << __i; |
| 149 | + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); |
| 150 | + *__result.__seg_ &= ~__m; |
| 151 | + *__result.__seg_ |= __w; |
| 152 | + __result.__ctz_ = __n; |
| 153 | + } |
| 154 | + return std::make_pair(std::move(__first), std::move(__result)); |
| 155 | +} |
| 156 | + |
| 157 | +template <class _InIter, class _Cp, __enable_if_t<__has_forward_iterator_category<_InIter>::value, int> = 0> |
| 158 | +pair<_InIter, __bit_iterator<_Cp, false>> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 159 | +__copy(_InIter __first, _InIter __last, __bit_iterator<_Cp, false> __result) { |
| 160 | + return std::__copy_bool(std::move(__first), std::move(__last), std::move(__result)); |
| 161 | +} |
| 162 | + |
106 | 163 | template <class _AlgPolicy, class _InIter, class _Sent, class _OutIter> |
107 | 164 | pair<_InIter, _OutIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
108 | 165 | __copy(_InIter __first, _Sent __last, _OutIter __result) { |
|
0 commit comments