|
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