|
10 | 10 | #ifndef _LIBCPP___BIT_REFERENCE |
11 | 11 | #define _LIBCPP___BIT_REFERENCE |
12 | 12 |
|
| 13 | +#include <__algorithm/copy_backward.h> |
13 | 14 | #include <__algorithm/copy_n.h> |
14 | 15 | #include <__algorithm/min.h> |
15 | 16 | #include <__bit/countr.h> |
@@ -293,134 +294,6 @@ copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last |
293 | 294 | return std::__copy_unaligned(__first, __last, __result); |
294 | 295 | } |
295 | 296 |
|
296 | | -// copy_backward |
297 | | - |
298 | | -template <class _Cp, bool _IsConst> |
299 | | -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_aligned( |
300 | | - __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { |
301 | | - using _In = __bit_iterator<_Cp, _IsConst>; |
302 | | - using difference_type = typename _In::difference_type; |
303 | | - using __storage_type = typename _In::__storage_type; |
304 | | - |
305 | | - const int __bits_per_word = _In::__bits_per_word; |
306 | | - difference_type __n = __last - __first; |
307 | | - if (__n > 0) { |
308 | | - // do first word |
309 | | - if (__last.__ctz_ != 0) { |
310 | | - difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n); |
311 | | - __n -= __dn; |
312 | | - unsigned __clz = __bits_per_word - __last.__ctz_; |
313 | | - __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); |
314 | | - __storage_type __b = *__last.__seg_ & __m; |
315 | | - *__result.__seg_ &= ~__m; |
316 | | - *__result.__seg_ |= __b; |
317 | | - __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); |
318 | | - // __last.__ctz_ = 0 |
319 | | - } |
320 | | - // __last.__ctz_ == 0 || __n == 0 |
321 | | - // __result.__ctz_ == 0 || __n == 0 |
322 | | - // do middle words |
323 | | - __storage_type __nw = __n / __bits_per_word; |
324 | | - __result.__seg_ -= __nw; |
325 | | - __last.__seg_ -= __nw; |
326 | | - std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_)); |
327 | | - __n -= __nw * __bits_per_word; |
328 | | - // do last word |
329 | | - if (__n > 0) { |
330 | | - __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); |
331 | | - __storage_type __b = *--__last.__seg_ & __m; |
332 | | - *--__result.__seg_ &= ~__m; |
333 | | - *__result.__seg_ |= __b; |
334 | | - __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); |
335 | | - } |
336 | | - } |
337 | | - return __result; |
338 | | -} |
339 | | - |
340 | | -template <class _Cp, bool _IsConst> |
341 | | -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_unaligned( |
342 | | - __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { |
343 | | - using _In = __bit_iterator<_Cp, _IsConst>; |
344 | | - using difference_type = typename _In::difference_type; |
345 | | - using __storage_type = typename _In::__storage_type; |
346 | | - |
347 | | - const int __bits_per_word = _In::__bits_per_word; |
348 | | - difference_type __n = __last - __first; |
349 | | - if (__n > 0) { |
350 | | - // do first word |
351 | | - if (__last.__ctz_ != 0) { |
352 | | - difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n); |
353 | | - __n -= __dn; |
354 | | - unsigned __clz_l = __bits_per_word - __last.__ctz_; |
355 | | - __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); |
356 | | - __storage_type __b = *__last.__seg_ & __m; |
357 | | - unsigned __clz_r = __bits_per_word - __result.__ctz_; |
358 | | - __storage_type __ddn = std::min(__dn, static_cast<difference_type>(__result.__ctz_)); |
359 | | - if (__ddn > 0) { |
360 | | - __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); |
361 | | - *__result.__seg_ &= ~__m; |
362 | | - if (__result.__ctz_ > __last.__ctz_) |
363 | | - *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); |
364 | | - else |
365 | | - *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); |
366 | | - __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); |
367 | | - __dn -= __ddn; |
368 | | - } |
369 | | - if (__dn > 0) { |
370 | | - // __result.__ctz_ == 0 |
371 | | - --__result.__seg_; |
372 | | - __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1)); |
373 | | - __m = ~__storage_type(0) << __result.__ctz_; |
374 | | - *__result.__seg_ &= ~__m; |
375 | | - __last.__ctz_ -= __dn + __ddn; |
376 | | - *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); |
377 | | - } |
378 | | - // __last.__ctz_ = 0 |
379 | | - } |
380 | | - // __last.__ctz_ == 0 || __n == 0 |
381 | | - // __result.__ctz_ != 0 || __n == 0 |
382 | | - // do middle words |
383 | | - unsigned __clz_r = __bits_per_word - __result.__ctz_; |
384 | | - __storage_type __m = ~__storage_type(0) >> __clz_r; |
385 | | - for (; __n >= __bits_per_word; __n -= __bits_per_word) { |
386 | | - __storage_type __b = *--__last.__seg_; |
387 | | - *__result.__seg_ &= ~__m; |
388 | | - *__result.__seg_ |= __b >> __clz_r; |
389 | | - *--__result.__seg_ &= __m; |
390 | | - *__result.__seg_ |= __b << __result.__ctz_; |
391 | | - } |
392 | | - // do last word |
393 | | - if (__n > 0) { |
394 | | - __m = ~__storage_type(0) << (__bits_per_word - __n); |
395 | | - __storage_type __b = *--__last.__seg_ & __m; |
396 | | - __clz_r = __bits_per_word - __result.__ctz_; |
397 | | - __storage_type __dn = std::min(__n, static_cast<difference_type>(__result.__ctz_)); |
398 | | - __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); |
399 | | - *__result.__seg_ &= ~__m; |
400 | | - *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); |
401 | | - __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); |
402 | | - __n -= __dn; |
403 | | - if (__n > 0) { |
404 | | - // __result.__ctz_ == 0 |
405 | | - --__result.__seg_; |
406 | | - __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); |
407 | | - __m = ~__storage_type(0) << __result.__ctz_; |
408 | | - *__result.__seg_ &= ~__m; |
409 | | - *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); |
410 | | - } |
411 | | - } |
412 | | - } |
413 | | - return __result; |
414 | | -} |
415 | | - |
416 | | -template <class _Cp, bool _IsConst> |
417 | | -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> copy_backward( |
418 | | - __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { |
419 | | - if (__last.__ctz_ == __result.__ctz_) |
420 | | - return std::__copy_backward_aligned(__first, __last, __result); |
421 | | - return std::__copy_backward_unaligned(__first, __last, __result); |
422 | | -} |
423 | | - |
424 | 297 | // move |
425 | 298 |
|
426 | 299 | template <class _Cp, bool _IsConst> |
@@ -983,9 +856,8 @@ private: |
983 | 856 | template <class _Dp, bool _IC> |
984 | 857 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_unaligned( |
985 | 858 | __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); |
986 | | - template <class _Dp, bool _IC> |
987 | | - _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> |
988 | | - copy_backward(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); |
| 859 | + template <class _AlgPolicy> |
| 860 | + friend struct __copy_backward_impl; |
989 | 861 | template <class _Cl, class _Cr> |
990 | 862 | friend __bit_iterator<_Cr, false> |
991 | 863 | __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
|
0 commit comments