1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
use crate::*; use core::mem; use frunk::hlist::{HCons, HNil}; use frunk_core::generic::Generic; /// ## Working Example /// This marker trait is implemented for structs iff it is `ReprC`, has no /// padding bytes, and all fields are also `FromZeros`: /// ```rust /// use typelayout::{ReprC, Generic, Layout, FromZeros}; /// /// #[derive(Generic, Default, Debug, PartialEq)] /// #[repr(C)] /// pub struct Struct { /// first: u8, /// second: u8, /// } /// /// unsafe impl ReprC for Struct {} /// /// assert_eq!(<Struct as Default>::default(), <Struct as FromZeros>::zeroed()); /// ``` /// /// ## Failing Example /// This marker trait is not implemented if a type has padding: /// ```compile_fail /// use typelayout::{ReprC, Generic, Layout, FromZeros}; /// /// #[derive(Generic, Default, Debug, PartialEq)] /// #[repr(C)] /// pub struct Struct { /// first: u8, /// second: u16, // padding will be inserted between `first` and `second` /// } /// /// unsafe impl ReprC for Struct {} /// /// // `Struct` does not implement `FromZeros`, because it has a padding byte! /// assert_eq!(<Struct as Default>::default(), <Struct as FromZeros>::zeroed()); /// ``` pub unsafe trait FromZeros { /// Initialize an instance of `Self` from zeroed bytes. #[inline(always)] fn zeroed() -> Self where Self: Sized, { unsafe { mem::zeroed() } } } /// A `*const T` from zeros is a null pointer. unsafe impl<T> FromZeros for *const T {} /// A `*mut T` from zeros is a null pointer. unsafe impl<T> FromZeros for *mut T {} unsafe impl FromZeros for i8 {} unsafe impl FromZeros for i16 {} unsafe impl FromZeros for i32 {} unsafe impl FromZeros for i64 {} unsafe impl FromZeros for i128 {} unsafe impl FromZeros for isize {} unsafe impl FromZeros for u8 {} unsafe impl FromZeros for u16 {} unsafe impl FromZeros for u32 {} unsafe impl FromZeros for u64 {} unsafe impl FromZeros for u128 {} unsafe impl FromZeros for usize {} unsafe impl FromZeros for f32 {} unsafe impl FromZeros for f64 {} /// A pub-in-priv wrapper type so we don't expose `FromZeros` implementations /// for arbitrary `HNil` and `HCons` instances. pub struct Struct<F>(F); unsafe impl<T: Generic + ReprC> FromZeros for T where T: NoPadding, Struct<<Self as Generic>::Repr>: FromZeros, {} unsafe impl FromZeros for Struct<HNil> {} unsafe impl<H, Tail> FromZeros for Struct<HCons<H, Tail>> where H: FromZeros, Struct<Tail>: FromZeros, {}