|
6 | 6 | // option. This file may not be copied, modified, or distributed
|
7 | 7 | // except according to those terms.
|
8 | 8 |
|
9 |
| -use std::mem::{size_of, ManuallyDrop}; |
| 9 | +use std::mem::{size_of, ManuallyDrop, MaybeUninit}; |
10 | 10 | use alloc::slice;
|
11 | 11 | use alloc::vec;
|
12 | 12 | use alloc::vec::Vec;
|
@@ -2462,10 +2462,24 @@ where
|
2462 | 2462 | Zip::from(tail.lanes_mut(axis)).for_each(|lane| {
|
2463 | 2463 | // TODO give ArrayViewMut1 a split_first method?
|
2464 | 2464 | let (mut fst, mut rest) = lane.split_at(Axis(0), 1);
|
| 2465 | + |
| 2466 | + // Logically we do a circular swap here, all elements in a chain |
| 2467 | + // Using MaybeUninit to avoid unecessary writes in the safe swap solution |
| 2468 | + // |
| 2469 | + // for elt in rest.iter_mut() { |
| 2470 | + // std::mem::swap(dst, elt); |
| 2471 | + // dst = elt; |
| 2472 | + // } |
| 2473 | + // |
| 2474 | + let mut slot = MaybeUninit::<A>::uninit(); |
2465 | 2475 | let mut dst = &mut fst[0];
|
2466 |
| - for elt in rest.iter_mut() { |
2467 |
| - std::mem::swap(dst, elt); |
2468 |
| - dst = elt; |
| 2476 | + unsafe { |
| 2477 | + slot.as_mut_ptr().copy_from_nonoverlapping(dst, 1); |
| 2478 | + for elt in rest.iter_mut() { |
| 2479 | + (dst as *mut A).copy_from_nonoverlapping(elt, 1); |
| 2480 | + dst = elt; |
| 2481 | + } |
| 2482 | + (dst as *mut A).copy_from_nonoverlapping(slot.as_ptr(), 1); |
2469 | 2483 | }
|
2470 | 2484 | });
|
2471 | 2485 | }
|
|
0 commit comments