#![allow(clippy::needless_range_loop)]
use std::mem;
use std::mem::MaybeUninit;
use std::ptr;
pub(crate) fn maybe_uninit_write_slice_cloned<'a, T>(
this: &'a mut [MaybeUninit<T>],
src: &[T],
) -> &'a mut [T]
where
T: Clone,
{
struct Guard<'a, T> {
slice: &'a mut [MaybeUninit<T>],
initialized: usize,
}
impl<'a, T> Drop for Guard<'a, T> {
fn drop(&mut self) {
let initialized_part = &mut self.slice[..self.initialized];
unsafe {
ptr::drop_in_place(&mut *(initialized_part as *mut [MaybeUninit<T>] as *mut [T]));
}
}
}
assert_eq!(
this.len(),
src.len(),
"destination and source slices have different lengths"
);
let len = this.len();
let src = &src[..len];
let mut guard = Guard {
slice: this,
initialized: 0,
};
for i in 0..len {
guard.slice[i].write(src[i].clone());
guard.initialized += 1;
}
mem::forget(guard);
unsafe { &mut *(this as *mut [MaybeUninit<T>] as *mut [T]) }
}
pub(crate) fn maybe_uninit_write_slice<'a, T>(
this: &'a mut [MaybeUninit<T>],
src: &[T],
) -> &'a mut [T]
where
T: Copy,
{
let uninit_src: &[MaybeUninit<T>] = unsafe { mem::transmute(src) };
this.copy_from_slice(uninit_src);
unsafe { &mut *(this as *mut [MaybeUninit<T>] as *mut [T]) }
}