Skip to content

Commit 7c195ab

Browse files
committed
Add specialization Random for integer arrays
Implements specialized `Random` for the array whose elements are integer primitives. This reduces the number of system calls.
1 parent 80d776e commit 7c195ab

File tree

1 file changed

+36
-2
lines changed

1 file changed

+36
-2
lines changed

Diff for: library/core/src/array/mod.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::ops::{
1818
};
1919
use crate::ptr::{null, null_mut};
2020
use crate::random::{Random, RandomSource};
21-
use crate::slice::{Iter, IterMut};
21+
use crate::slice::{self, Iter, IterMut};
2222

2323
mod ascii;
2424
mod drain;
@@ -429,11 +429,45 @@ impl<T: Clone, const N: usize> Clone for [T; N] {
429429

430430
#[unstable(feature = "random", issue = "130703")]
431431
impl<T: Random, const N: usize> Random for [T; N] {
432-
fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
432+
default fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
433433
from_fn(|_| T::random(source))
434434
}
435435
}
436436

437+
macro_rules! impl_random_for_integer_array {
438+
($t:ty) => {
439+
#[unstable(feature = "random", issue = "130703")]
440+
impl<const N: usize> Random for [$t; N] {
441+
fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
442+
let mut buf = [const { MaybeUninit::<$t>::uninit() }; N];
443+
// SAFETY: all elements in the buffer were initialized with
444+
// random bytes.
445+
unsafe {
446+
let bytes = slice::from_raw_parts_mut(
447+
&raw mut buf as *mut u8,
448+
N * mem::size_of::<$t>(),
449+
);
450+
source.fill_bytes(bytes);
451+
mem::transmute_copy(&buf)
452+
}
453+
}
454+
}
455+
};
456+
}
457+
458+
impl_random_for_integer_array!(u8);
459+
impl_random_for_integer_array!(u16);
460+
impl_random_for_integer_array!(u32);
461+
impl_random_for_integer_array!(u64);
462+
impl_random_for_integer_array!(u128);
463+
impl_random_for_integer_array!(usize);
464+
impl_random_for_integer_array!(i8);
465+
impl_random_for_integer_array!(i16);
466+
impl_random_for_integer_array!(i32);
467+
impl_random_for_integer_array!(i64);
468+
impl_random_for_integer_array!(i128);
469+
impl_random_for_integer_array!(isize);
470+
437471
trait SpecArrayClone: Clone {
438472
fn clone<const N: usize>(array: &[Self; N]) -> [Self; N];
439473
}

0 commit comments

Comments
 (0)