Skip to content

Commit 4c96015

Browse files
committed
Support AsByteSliceMut on Wrapping<T> types
1 parent d062fc5 commit 4c96015

File tree

1 file changed

+46
-23
lines changed

1 file changed

+46
-23
lines changed

src/lib.rs

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ pub mod seq;
9292

9393

9494
use core::{mem, slice};
95+
use core::num::Wrapping;
9596
use distributions::{Distribution, Standard};
9697
use distributions::uniform::{SampleUniform, UniformSampler, SampleBorrow};
9798

@@ -398,6 +399,7 @@ impl AsByteSliceMut for [u8] {
398399
}
399400

400401
macro_rules! impl_as_byte_slice {
402+
() => {};
401403
($t:ty) => {
402404
impl AsByteSliceMut for [$t] {
403405
fn as_byte_slice_mut(&mut self) -> &mut [u8] {
@@ -422,26 +424,47 @@ macro_rules! impl_as_byte_slice {
422424
}
423425
}
424426
}
427+
428+
impl AsByteSliceMut for [Wrapping<$t>] {
429+
fn as_byte_slice_mut(&mut self) -> &mut [u8] {
430+
if self.len() == 0 {
431+
unsafe {
432+
// must not use null pointer
433+
slice::from_raw_parts_mut(0x1 as *mut u8, 0)
434+
}
435+
} else {
436+
unsafe {
437+
slice::from_raw_parts_mut(self.as_mut_ptr()
438+
as *mut u8,
439+
self.len() * mem::size_of::<$t>()
440+
)
441+
}
442+
}
443+
}
444+
445+
fn to_le(&mut self) {
446+
for x in self {
447+
*x = Wrapping(x.0.to_le());
448+
}
449+
}
450+
}
451+
};
452+
($t:ty, $($tt:ty,)*) => {
453+
impl_as_byte_slice!($t);
454+
// TODO: this could replace above impl once Rust #32463 is fixed
455+
// impl_as_byte_slice!(Wrapping<$t>);
456+
impl_as_byte_slice!($($tt,)*);
425457
}
426458
}
427459

428-
impl_as_byte_slice!(u16);
429-
impl_as_byte_slice!(u32);
430-
impl_as_byte_slice!(u64);
460+
impl_as_byte_slice!(u16, u32, u64, usize,);
431461
#[cfg(all(rustc_1_26, not(target_os = "emscripten")))] impl_as_byte_slice!(u128);
432-
impl_as_byte_slice!(usize);
433-
impl_as_byte_slice!(i8);
434-
impl_as_byte_slice!(i16);
435-
impl_as_byte_slice!(i32);
436-
impl_as_byte_slice!(i64);
462+
impl_as_byte_slice!(i8, i16, i32, i64, isize,);
437463
#[cfg(all(rustc_1_26, not(target_os = "emscripten")))] impl_as_byte_slice!(i128);
438-
impl_as_byte_slice!(isize);
439464

440465
macro_rules! impl_as_byte_slice_arrays {
441466
($n:expr,) => {};
442-
($n:expr, $N:ident, $($NN:ident,)*) => {
443-
impl_as_byte_slice_arrays!($n - 1, $($NN,)*);
444-
467+
($n:expr, $N:ident) => {
445468
impl<T> AsByteSliceMut for [T; $n] where [T]: AsByteSliceMut {
446469
fn as_byte_slice_mut(&mut self) -> &mut [u8] {
447470
self[..].as_byte_slice_mut()
@@ -452,25 +475,19 @@ macro_rules! impl_as_byte_slice_arrays {
452475
}
453476
}
454477
};
478+
($n:expr, $N:ident, $($NN:ident,)*) => {
479+
impl_as_byte_slice_arrays!($n, $N);
480+
impl_as_byte_slice_arrays!($n - 1, $($NN,)*);
481+
};
455482
(!div $n:expr,) => {};
456483
(!div $n:expr, $N:ident, $($NN:ident,)*) => {
484+
impl_as_byte_slice_arrays!($n, $N);
457485
impl_as_byte_slice_arrays!(!div $n / 2, $($NN,)*);
458-
459-
impl<T> AsByteSliceMut for [T; $n] where [T]: AsByteSliceMut {
460-
fn as_byte_slice_mut(&mut self) -> &mut [u8] {
461-
self[..].as_byte_slice_mut()
462-
}
463-
464-
fn to_le(&mut self) {
465-
self[..].to_le()
466-
}
467-
}
468486
};
469487
}
470488
impl_as_byte_slice_arrays!(32, N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,);
471489
impl_as_byte_slice_arrays!(!div 4096, N,N,N,N,N,N,N,);
472490

473-
474491
/// Generates a random value using the thread-local random number generator.
475492
///
476493
/// This is simply a shortcut for `thread_rng().gen()`. See [`thread_rng`] for
@@ -568,6 +585,12 @@ mod test {
568585
rng.fill(&mut array[..]);
569586
assert_eq!(array, [x as u32, (x >> 32) as u32]);
570587
assert_eq!(rng.next_u32(), x as u32);
588+
589+
// Check equivalence using wrapped arrays
590+
let mut warray = [Wrapping(0u32); 2];
591+
rng.fill(&mut warray[..]);
592+
assert_eq!(array[0], warray[0].0);
593+
assert_eq!(array[1], warray[1].0);
571594
}
572595

573596
#[test]

0 commit comments

Comments
 (0)