|
14 | 14 | #include <__algorithm/copy_backward.h> |
15 | 15 | #include <__algorithm/copy_n.h> |
16 | 16 | #include <__algorithm/min.h> |
| 17 | +#include <__algorithm/swap_ranges.h> |
17 | 18 | #include <__assert> |
18 | 19 | #include <__bit/countr.h> |
19 | 20 | #include <__compare/ordering.h> |
@@ -226,152 +227,6 @@ inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> move_backward( |
226 | 227 | return std::copy_backward(__first, __last, __result); |
227 | 228 | } |
228 | 229 |
|
229 | | -// swap_ranges |
230 | | - |
231 | | -template <class _Cl, class _Cr> |
232 | | -_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_aligned( |
233 | | - __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) { |
234 | | - using _I1 = __bit_iterator<_Cl, false>; |
235 | | - using difference_type = typename _I1::difference_type; |
236 | | - using __storage_type = typename _I1::__storage_type; |
237 | | - |
238 | | - const int __bits_per_word = _I1::__bits_per_word; |
239 | | - difference_type __n = __last - __first; |
240 | | - if (__n > 0) { |
241 | | - // do first word |
242 | | - if (__first.__ctz_ != 0) { |
243 | | - unsigned __clz = __bits_per_word - __first.__ctz_; |
244 | | - difference_type __dn = std::min(static_cast<difference_type>(__clz), __n); |
245 | | - __n -= __dn; |
246 | | - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); |
247 | | - __storage_type __b1 = *__first.__seg_ & __m; |
248 | | - *__first.__seg_ &= ~__m; |
249 | | - __storage_type __b2 = *__result.__seg_ & __m; |
250 | | - *__result.__seg_ &= ~__m; |
251 | | - *__result.__seg_ |= __b1; |
252 | | - *__first.__seg_ |= __b2; |
253 | | - __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; |
254 | | - __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); |
255 | | - ++__first.__seg_; |
256 | | - // __first.__ctz_ = 0; |
257 | | - } |
258 | | - // __first.__ctz_ == 0; |
259 | | - // do middle words |
260 | | - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) |
261 | | - swap(*__first.__seg_, *__result.__seg_); |
262 | | - // do last word |
263 | | - if (__n > 0) { |
264 | | - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); |
265 | | - __storage_type __b1 = *__first.__seg_ & __m; |
266 | | - *__first.__seg_ &= ~__m; |
267 | | - __storage_type __b2 = *__result.__seg_ & __m; |
268 | | - *__result.__seg_ &= ~__m; |
269 | | - *__result.__seg_ |= __b1; |
270 | | - *__first.__seg_ |= __b2; |
271 | | - __result.__ctz_ = static_cast<unsigned>(__n); |
272 | | - } |
273 | | - } |
274 | | - return __result; |
275 | | -} |
276 | | - |
277 | | -template <class _Cl, class _Cr> |
278 | | -_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_unaligned( |
279 | | - __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) { |
280 | | - using _I1 = __bit_iterator<_Cl, false>; |
281 | | - using difference_type = typename _I1::difference_type; |
282 | | - using __storage_type = typename _I1::__storage_type; |
283 | | - |
284 | | - const int __bits_per_word = _I1::__bits_per_word; |
285 | | - difference_type __n = __last - __first; |
286 | | - if (__n > 0) { |
287 | | - // do first word |
288 | | - if (__first.__ctz_ != 0) { |
289 | | - unsigned __clz_f = __bits_per_word - __first.__ctz_; |
290 | | - difference_type __dn = std::min(static_cast<difference_type>(__clz_f), __n); |
291 | | - __n -= __dn; |
292 | | - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); |
293 | | - __storage_type __b1 = *__first.__seg_ & __m; |
294 | | - *__first.__seg_ &= ~__m; |
295 | | - unsigned __clz_r = __bits_per_word - __result.__ctz_; |
296 | | - __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); |
297 | | - __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); |
298 | | - __storage_type __b2 = *__result.__seg_ & __m; |
299 | | - *__result.__seg_ &= ~__m; |
300 | | - if (__result.__ctz_ > __first.__ctz_) { |
301 | | - unsigned __s = __result.__ctz_ - __first.__ctz_; |
302 | | - *__result.__seg_ |= __b1 << __s; |
303 | | - *__first.__seg_ |= __b2 >> __s; |
304 | | - } else { |
305 | | - unsigned __s = __first.__ctz_ - __result.__ctz_; |
306 | | - *__result.__seg_ |= __b1 >> __s; |
307 | | - *__first.__seg_ |= __b2 << __s; |
308 | | - } |
309 | | - __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; |
310 | | - __result.__ctz_ = static_cast<unsigned>((__ddn + __result.__ctz_) % __bits_per_word); |
311 | | - __dn -= __ddn; |
312 | | - if (__dn > 0) { |
313 | | - __m = ~__storage_type(0) >> (__bits_per_word - __dn); |
314 | | - __b2 = *__result.__seg_ & __m; |
315 | | - *__result.__seg_ &= ~__m; |
316 | | - unsigned __s = __first.__ctz_ + __ddn; |
317 | | - *__result.__seg_ |= __b1 >> __s; |
318 | | - *__first.__seg_ |= __b2 << __s; |
319 | | - __result.__ctz_ = static_cast<unsigned>(__dn); |
320 | | - } |
321 | | - ++__first.__seg_; |
322 | | - // __first.__ctz_ = 0; |
323 | | - } |
324 | | - // __first.__ctz_ == 0; |
325 | | - // do middle words |
326 | | - __storage_type __m = ~__storage_type(0) << __result.__ctz_; |
327 | | - unsigned __clz_r = __bits_per_word - __result.__ctz_; |
328 | | - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) { |
329 | | - __storage_type __b1 = *__first.__seg_; |
330 | | - __storage_type __b2 = *__result.__seg_ & __m; |
331 | | - *__result.__seg_ &= ~__m; |
332 | | - *__result.__seg_ |= __b1 << __result.__ctz_; |
333 | | - *__first.__seg_ = __b2 >> __result.__ctz_; |
334 | | - ++__result.__seg_; |
335 | | - __b2 = *__result.__seg_ & ~__m; |
336 | | - *__result.__seg_ &= __m; |
337 | | - *__result.__seg_ |= __b1 >> __clz_r; |
338 | | - *__first.__seg_ |= __b2 << __clz_r; |
339 | | - } |
340 | | - // do last word |
341 | | - if (__n > 0) { |
342 | | - __m = ~__storage_type(0) >> (__bits_per_word - __n); |
343 | | - __storage_type __b1 = *__first.__seg_ & __m; |
344 | | - *__first.__seg_ &= ~__m; |
345 | | - __storage_type __dn = std::min<__storage_type>(__n, __clz_r); |
346 | | - __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); |
347 | | - __storage_type __b2 = *__result.__seg_ & __m; |
348 | | - *__result.__seg_ &= ~__m; |
349 | | - *__result.__seg_ |= __b1 << __result.__ctz_; |
350 | | - *__first.__seg_ |= __b2 >> __result.__ctz_; |
351 | | - __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; |
352 | | - __result.__ctz_ = static_cast<unsigned>((__dn + __result.__ctz_) % __bits_per_word); |
353 | | - __n -= __dn; |
354 | | - if (__n > 0) { |
355 | | - __m = ~__storage_type(0) >> (__bits_per_word - __n); |
356 | | - __b2 = *__result.__seg_ & __m; |
357 | | - *__result.__seg_ &= ~__m; |
358 | | - *__result.__seg_ |= __b1 >> __dn; |
359 | | - *__first.__seg_ |= __b2 << __dn; |
360 | | - __result.__ctz_ = static_cast<unsigned>(__n); |
361 | | - } |
362 | | - } |
363 | | - } |
364 | | - return __result; |
365 | | -} |
366 | | - |
367 | | -template <class _Cl, class _Cr> |
368 | | -inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges( |
369 | | - __bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1, __bit_iterator<_Cr, false> __first2) { |
370 | | - if (__first1.__ctz_ == __first2.__ctz_) |
371 | | - return std::__swap_ranges_aligned(__first1, __last1, __first2); |
372 | | - return std::__swap_ranges_unaligned(__first1, __last1, __first2); |
373 | | -} |
374 | | - |
375 | 230 | // rotate |
376 | 231 |
|
377 | 232 | template <class _Cp> |
@@ -776,14 +631,14 @@ private: |
776 | 631 | template <class _AlgPolicy> |
777 | 632 | friend struct __copy_backward_impl; |
778 | 633 | template <class _Cl, class _Cr> |
779 | | - friend __bit_iterator<_Cr, false> |
| 634 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Cr, false> |
780 | 635 | __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
781 | 636 | template <class _Cl, class _Cr> |
782 | | - friend __bit_iterator<_Cr, false> |
| 637 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Cr, false> |
783 | 638 | __swap_ranges_unaligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
784 | | - template <class _Cl, class _Cr> |
785 | | - friend __bit_iterator<_Cr, false> |
786 | | - swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
| 639 | + template <class, class _Cl, class _Cr> |
| 640 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend pair<__bit_iterator<_Cl, false>, __bit_iterator<_Cr, false> > |
| 641 | + __swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); |
787 | 642 | template <class _Dp> |
788 | 643 | _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> |
789 | 644 | rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>); |
|
0 commit comments