Skip to content

Commit 0100285

Browse files
committed
core: add slice::write_default
1 parent 88ed708 commit 0100285

2 files changed

Lines changed: 70 additions & 39 deletions

File tree

library/core/src/io/borrowed_buf.rs

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -362,47 +362,11 @@ impl<'a, T: Default + Copy> BorrowedCursor<'a, T> {
362362
#[unstable(feature = "borrowed_buf_init", issue = "160476")]
363363
#[inline]
364364
pub fn ensure_init(&mut self) -> &mut [T] {
365-
trait InitSpec: Default + Copy {
366-
fn initialize(buf: &mut [MaybeUninit<Self>]);
367-
}
368-
369-
impl<T: Default + Copy> InitSpec for T {
370-
default fn initialize(buf: &mut [MaybeUninit<Self>]) {
371-
buf.write_with(|_| Self::default());
372-
}
373-
}
374-
375-
macro_rules! spec_zero_init {
376-
($ty:ty) => {
377-
impl InitSpec for $ty {
378-
fn initialize(buf: &mut [MaybeUninit<Self>]) {
379-
// SAFETY: all these types can be zero-initialized.
380-
unsafe {
381-
buf.as_mut_ptr().write_bytes(0, buf.len());
382-
}
383-
}
384-
}
385-
};
386-
}
387-
388-
spec_zero_init!(i8);
389-
spec_zero_init!(u8);
390-
spec_zero_init!(i16);
391-
spec_zero_init!(u16);
392-
spec_zero_init!(i32);
393-
spec_zero_init!(u32);
394-
spec_zero_init!(i64);
395-
spec_zero_init!(u64);
396-
spec_zero_init!(i128);
397-
spec_zero_init!(u128);
398-
spec_zero_init!(isize);
399-
spec_zero_init!(usize);
400-
401365
// SAFETY: always in bounds and we never uninitialize these elements.
402366
let unfilled = unsafe { self.buf.buf.get_unchecked_mut(self.buf.filled..) };
403367

404368
if !self.buf.init {
405-
InitSpec::initialize(unfilled);
369+
unfilled.write_default();
406370
self.buf.init = true;
407371
}
408372

library/core/src/mem/maybe_uninit.rs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,8 +1286,8 @@ impl<T> [MaybeUninit<T>] {
12861286
/// Fills a slice with elements returned by calling a closure for each index.
12871287
///
12881288
/// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
1289-
/// [slice::write_filled]. If you want to use the `Default` trait to generate values, you can
1290-
/// pass [`|_| Default::default()`][Default::default] as the argument.
1289+
/// [`slice::write_filled`]. If you want to use the `Default` trait to generate values, use
1290+
/// [`slice::write_default`].
12911291
///
12921292
/// # Panics
12931293
///
@@ -1324,6 +1324,73 @@ impl<T> [MaybeUninit<T>] {
13241324
unsafe { self.assume_init_mut() }
13251325
}
13261326

1327+
/// Fills a slice with elements returned by calling [`Default::default`] for each index.
1328+
///
1329+
/// # Panics
1330+
///
1331+
/// This function will panic if any call to [`Default::default`] panics.
1332+
///
1333+
/// If such a panic occurs, any elements previously initialized during this operation will be
1334+
/// dropped.
1335+
///
1336+
/// # Examples
1337+
///
1338+
/// ```
1339+
/// #![feature(maybe_uninit_fill)]
1340+
/// use std::mem::MaybeUninit;
1341+
///
1342+
/// let mut buf = [const { MaybeUninit::<usize>::uninit() }; 5];
1343+
/// let initialized = buf.write_default();
1344+
/// assert_eq!(initialized, &mut [0, 0, 0, 0, 0]);
1345+
/// ```
1346+
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
1347+
pub fn write_default(&mut self) -> &mut [T]
1348+
where
1349+
T: Default,
1350+
{
1351+
trait DefaultSpec: Default {
1352+
fn write_default(buf: &mut [MaybeUninit<Self>]) -> &mut [Self];
1353+
}
1354+
1355+
impl<T: Default> DefaultSpec for T {
1356+
default fn write_default(buf: &mut [MaybeUninit<Self>]) -> &mut [Self] {
1357+
buf.write_with(|_| T::default())
1358+
}
1359+
}
1360+
1361+
macro_rules! spec_default_zero {
1362+
($ty:ty) => {
1363+
impl DefaultSpec for $ty {
1364+
fn write_default(buf: &mut [MaybeUninit<Self>]) -> &mut [Self] {
1365+
// SAFETY:
1366+
// `Default::default` is equivalent to zero-initialization
1367+
// for all these types, and this initializes the entire
1368+
// slice.
1369+
unsafe {
1370+
buf.as_mut_ptr().write_bytes(0, buf.len());
1371+
buf.assume_init_mut()
1372+
}
1373+
}
1374+
}
1375+
};
1376+
}
1377+
1378+
spec_default_zero!(i8);
1379+
spec_default_zero!(u8);
1380+
spec_default_zero!(i16);
1381+
spec_default_zero!(u16);
1382+
spec_default_zero!(i32);
1383+
spec_default_zero!(u32);
1384+
spec_default_zero!(i64);
1385+
spec_default_zero!(u64);
1386+
spec_default_zero!(i128);
1387+
spec_default_zero!(u128);
1388+
spec_default_zero!(isize);
1389+
spec_default_zero!(usize);
1390+
1391+
T::write_default(self)
1392+
}
1393+
13271394
/// Fills a slice with elements yielded by an iterator until either all elements have been
13281395
/// initialized or the iterator is empty.
13291396
///

0 commit comments

Comments
 (0)