1 use { 2 crate::{Arbitrary, Error, MaxRecursionReached, Result, Unstructured}, 3 core::{ 4 mem, 5 num::{ 6 NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128, 7 NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping, 8 }, 9 }, 10 }; 11 12 macro_rules! impl_arbitrary_for_integers { 13 ( $( $ty:ty; )* ) => { 14 $( 15 impl<'a> Arbitrary<'a> for $ty { 16 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> { 17 let mut buf = [0; mem::size_of::<$ty>()]; 18 u.fill_buffer(&mut buf)?; 19 Ok(Self::from_le_bytes(buf)) 20 } 21 22 #[inline] 23 fn size_hint(_depth: usize) -> (usize, Option<usize>) { 24 let n = mem::size_of::<$ty>(); 25 (n, Some(n)) 26 } 27 28 } 29 )* 30 } 31 } 32 33 impl_arbitrary_for_integers! { 34 u8; 35 u16; 36 u32; 37 u64; 38 u128; 39 i8; 40 i16; 41 i32; 42 i64; 43 i128; 44 } 45 46 // Note: We forward Arbitrary for i/usize to i/u64 in order to simplify corpus 47 // compatibility between 32-bit and 64-bit builds. This introduces dead space in 48 // 32-bit builds but keeps the input layout independent of the build platform. 49 impl<'a> Arbitrary<'a> for usize { arbitrary(u: &mut Unstructured<'a>) -> Result<Self>50 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> { 51 u.arbitrary::<u64>().map(|x| x as usize) 52 } 53 54 #[inline] size_hint(depth: usize) -> (usize, Option<usize>)55 fn size_hint(depth: usize) -> (usize, Option<usize>) { 56 <u64 as Arbitrary>::size_hint(depth) 57 } 58 } 59 60 impl<'a> Arbitrary<'a> for isize { arbitrary(u: &mut Unstructured<'a>) -> Result<Self>61 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> { 62 u.arbitrary::<i64>().map(|x| x as isize) 63 } 64 65 #[inline] size_hint(depth: usize) -> (usize, Option<usize>)66 fn size_hint(depth: usize) -> (usize, Option<usize>) { 67 <i64 as Arbitrary>::size_hint(depth) 68 } 69 } 70 71 macro_rules! impl_arbitrary_for_floats { 72 ( $( $ty:ident : $unsigned:ty; )* ) => { 73 $( 74 impl<'a> Arbitrary<'a> for $ty { 75 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> { 76 Ok(Self::from_bits(<$unsigned as Arbitrary<'a>>::arbitrary(u)?)) 77 } 78 79 #[inline] 80 fn size_hint(depth: usize) -> (usize, Option<usize>) { 81 <$unsigned as Arbitrary<'a>>::size_hint(depth) 82 } 83 } 84 )* 85 } 86 } 87 88 impl_arbitrary_for_floats! { 89 f32: u32; 90 f64: u64; 91 } 92 93 macro_rules! implement_nonzero_int { 94 ($nonzero:ty, $int:ty) => { 95 impl<'a> Arbitrary<'a> for $nonzero { 96 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> { 97 match Self::new(<$int as Arbitrary<'a>>::arbitrary(u)?) { 98 Some(n) => Ok(n), 99 None => Err(Error::IncorrectFormat), 100 } 101 } 102 103 #[inline] 104 fn size_hint(depth: usize) -> (usize, Option<usize>) { 105 <$int as Arbitrary<'a>>::size_hint(depth) 106 } 107 } 108 }; 109 } 110 111 implement_nonzero_int! { NonZeroI8, i8 } 112 implement_nonzero_int! { NonZeroI16, i16 } 113 implement_nonzero_int! { NonZeroI32, i32 } 114 implement_nonzero_int! { NonZeroI64, i64 } 115 implement_nonzero_int! { NonZeroI128, i128 } 116 implement_nonzero_int! { NonZeroIsize, isize } 117 implement_nonzero_int! { NonZeroU8, u8 } 118 implement_nonzero_int! { NonZeroU16, u16 } 119 implement_nonzero_int! { NonZeroU32, u32 } 120 implement_nonzero_int! { NonZeroU64, u64 } 121 implement_nonzero_int! { NonZeroU128, u128 } 122 implement_nonzero_int! { NonZeroUsize, usize } 123 124 impl<'a, A> Arbitrary<'a> for Wrapping<A> 125 where 126 A: Arbitrary<'a>, 127 { arbitrary(u: &mut Unstructured<'a>) -> Result<Self>128 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> { 129 Arbitrary::arbitrary(u).map(Wrapping) 130 } 131 132 #[inline] size_hint(depth: usize) -> (usize, Option<usize>)133 fn size_hint(depth: usize) -> (usize, Option<usize>) { 134 Self::try_size_hint(depth).unwrap_or_default() 135 } 136 137 #[inline] try_size_hint(depth: usize) -> Result<(usize, Option<usize>), MaxRecursionReached>138 fn try_size_hint(depth: usize) -> Result<(usize, Option<usize>), MaxRecursionReached> { 139 <A as Arbitrary<'a>>::try_size_hint(depth) 140 } 141 } 142