|
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>
|
@@ -307,134 +308,6 @@ copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last
|
307 | 308 | return std::__copy_unaligned(__first, __last, __result);
|
308 | 309 | }
|
309 | 310 |
|
310 |
| -// copy_backward |
311 |
| - |
312 |
| -template <class _Cp, bool _IsConst> |
313 |
| -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_aligned( |
314 |
| - __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { |
315 |
| - using _In = __bit_iterator<_Cp, _IsConst>; |
316 |
| - using difference_type = typename _In::difference_type; |
317 |
| - using __storage_type = typename _In::__storage_type; |
318 |
| - |
319 |
| - const int __bits_per_word = _In::__bits_per_word; |
320 |
| - difference_type __n = __last - __first; |
321 |
| - if (__n > 0) { |
322 |
| - // do first word |
323 |
| - if (__last.__ctz_ != 0) { |
324 |
| - difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n); |
325 |
| - __n -= __dn; |
326 |
| - unsigned __clz = __bits_per_word - __last.__ctz_; |
327 |
| - __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); |
328 |
| - __storage_type __b = *__last.__seg_ & __m; |
329 |
| - *__result.__seg_ &= ~__m; |
330 |
| - *__result.__seg_ |= __b; |
331 |
| - __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); |
332 |
| - // __last.__ctz_ = 0 |
333 |
| - } |
334 |
| - // __last.__ctz_ == 0 || __n == 0 |
335 |
| - // __result.__ctz_ == 0 || __n == 0 |
336 |
| - // do middle words |
337 |
| - __storage_type __nw = __n / __bits_per_word; |
338 |
| - __result.__seg_ -= __nw; |
339 |
| - __last.__seg_ -= __nw; |
340 |
| - std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_)); |
341 |
| - __n -= __nw * __bits_per_word; |
342 |
| - // do last word |
343 |
| - if (__n > 0) { |
344 |
| - __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); |
345 |
| - __storage_type __b = *--__last.__seg_ & __m; |
346 |
| - *--__result.__seg_ &= ~__m; |
347 |
| - *__result.__seg_ |= __b; |
348 |
| - __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); |
349 |
| - } |
350 |
| - } |
351 |
| - return __result; |
352 |
| -} |
353 |
| - |
354 |
| -template <class _Cp, bool _IsConst> |
355 |
| -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_unaligned( |
356 |
| - __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { |
357 |
| - using _In = __bit_iterator<_Cp, _IsConst>; |
358 |
| - using difference_type = typename _In::difference_type; |
359 |
| - using __storage_type = typename _In::__storage_type; |
360 |
| - |
361 |
| - const int __bits_per_word = _In::__bits_per_word; |
362 |
| - difference_type __n = __last - __first; |
363 |
| - if (__n > 0) { |
364 |
| - // do first word |
365 |
| - if (__last.__ctz_ != 0) { |
366 |
| - difference_type __dn = std::min(static_cast<difference_type>(__last.__ctz_), __n); |
367 |
| - __n -= __dn; |
368 |
| - unsigned __clz_l = __bits_per_word - __last.__ctz_; |
369 |
| - __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); |
370 |
| - __storage_type __b = *__last.__seg_ & __m; |
371 |
| - unsigned __clz_r = __bits_per_word - __result.__ctz_; |
372 |
| - __storage_type __ddn = std::min(__dn, static_cast<difference_type>(__result.__ctz_)); |
373 |
| - if (__ddn > 0) { |
374 |
| - __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); |
375 |
| - *__result.__seg_ &= ~__m; |
376 |
| - if (__result.__ctz_ > __last.__ctz_) |
377 |
| - *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); |
378 |
| - else |
379 |
| - *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); |
380 |
| - __result.__ctz_ = static_cast<unsigned>(((-__ddn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); |
381 |
| - __dn -= __ddn; |
382 |
| - } |
383 |
| - if (__dn > 0) { |
384 |
| - // __result.__ctz_ == 0 |
385 |
| - --__result.__seg_; |
386 |
| - __result.__ctz_ = static_cast<unsigned>(-__dn & (__bits_per_word - 1)); |
387 |
| - __m = ~__storage_type(0) << __result.__ctz_; |
388 |
| - *__result.__seg_ &= ~__m; |
389 |
| - __last.__ctz_ -= __dn + __ddn; |
390 |
| - *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); |
391 |
| - } |
392 |
| - // __last.__ctz_ = 0 |
393 |
| - } |
394 |
| - // __last.__ctz_ == 0 || __n == 0 |
395 |
| - // __result.__ctz_ != 0 || __n == 0 |
396 |
| - // do middle words |
397 |
| - unsigned __clz_r = __bits_per_word - __result.__ctz_; |
398 |
| - __storage_type __m = ~__storage_type(0) >> __clz_r; |
399 |
| - for (; __n >= __bits_per_word; __n -= __bits_per_word) { |
400 |
| - __storage_type __b = *--__last.__seg_; |
401 |
| - *__result.__seg_ &= ~__m; |
402 |
| - *__result.__seg_ |= __b >> __clz_r; |
403 |
| - *--__result.__seg_ &= __m; |
404 |
| - *__result.__seg_ |= __b << __result.__ctz_; |
405 |
| - } |
406 |
| - // do last word |
407 |
| - if (__n > 0) { |
408 |
| - __m = ~__storage_type(0) << (__bits_per_word - __n); |
409 |
| - __storage_type __b = *--__last.__seg_ & __m; |
410 |
| - __clz_r = __bits_per_word - __result.__ctz_; |
411 |
| - __storage_type __dn = std::min(__n, static_cast<difference_type>(__result.__ctz_)); |
412 |
| - __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); |
413 |
| - *__result.__seg_ &= ~__m; |
414 |
| - *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); |
415 |
| - __result.__ctz_ = static_cast<unsigned>(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); |
416 |
| - __n -= __dn; |
417 |
| - if (__n > 0) { |
418 |
| - // __result.__ctz_ == 0 |
419 |
| - --__result.__seg_; |
420 |
| - __result.__ctz_ = static_cast<unsigned>(-__n & (__bits_per_word - 1)); |
421 |
| - __m = ~__storage_type(0) << __result.__ctz_; |
422 |
| - *__result.__seg_ &= ~__m; |
423 |
| - *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); |
424 |
| - } |
425 |
| - } |
426 |
| - } |
427 |
| - return __result; |
428 |
| -} |
429 |
| - |
430 |
| -template <class _Cp, bool _IsConst> |
431 |
| -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> copy_backward( |
432 |
| - __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { |
433 |
| - if (__last.__ctz_ == __result.__ctz_) |
434 |
| - return std::__copy_backward_aligned(__first, __last, __result); |
435 |
| - return std::__copy_backward_unaligned(__first, __last, __result); |
436 |
| -} |
437 |
| - |
438 | 311 | // move
|
439 | 312 |
|
440 | 313 | template <class _Cp, bool _IsConst>
|
@@ -997,9 +870,10 @@ private:
|
997 | 870 | template <class _Dp, bool _IC>
|
998 | 871 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_unaligned(
|
999 | 872 | __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result);
|
1000 |
| - template <class _Dp, bool _IC> |
1001 |
| - _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> |
1002 |
| - copy_backward(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); |
| 873 | + // Note: dependent nested name specifier __copy_backward_impl<_AlgPolicy>::operator() for friend declaration |
| 874 | + // is not supported in clang. Thus, we use a friend declaration for the entire class. |
| 875 | + template <class _AlgPolicy> |
| 876 | + friend struct __copy_backward_impl; |
1003 | 877 | template <class _Cl, class _Cr>
|
1004 | 878 | friend __bit_iterator<_Cr, false>
|
1005 | 879 | __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>);
|
|
0 commit comments