1 use core::mem; 2 use core::ptr::{self, NonNull}; 3 4 /// Copy the bytes of `val` to `ptr`, then advance pointer to just after the 5 /// newly-copied bytes. ptr_write_unaligned_and_add<T>(ptr: &mut *mut u8, val: T)6pub unsafe fn ptr_write_unaligned_and_add<T>(ptr: &mut *mut u8, val: T) { 7 ptr.cast::<T>().write_unaligned(val); 8 *ptr = ptr.add(mem::size_of::<T>()); 9 } 10 11 /// Convert from a `u32` to a `usize`. Panic if the input does fit. On typical 12 /// targets `usize` is at least as big as `u32`, so this should never panic 13 /// except on unusual targets. 14 /// 15 /// Comparison to alternatives: 16 /// * `val as usize` doesn't check that `val` actually fits in a `usize`. 17 /// * `usize::try_from(val).unwrap()` doesn't work in a const context. usize_from_u32(val: u32) -> usize18pub const fn usize_from_u32(val: u32) -> usize { 19 // This is essentially the same as `usize::try_from(val).unwrap()`, but 20 // works in a `const` context on stable. 21 if mem::size_of::<usize>() < mem::size_of::<u32>() && val < (usize::MAX as u32) { 22 panic!("value does not fit in a usize"); 23 } else { 24 val as usize 25 } 26 } 27 28 /// Get the raw pointer from `opt`, defaulting to `null_mut`. opt_nonnull_to_ptr<T>(opt: Option<NonNull<T>>) -> *mut T29pub fn opt_nonnull_to_ptr<T>(opt: Option<NonNull<T>>) -> *mut T { 30 opt.map(NonNull::as_ptr).unwrap_or(ptr::null_mut()) 31 } 32 33 #[cfg(test)] 34 mod tests { 35 use super::*; 36 37 #[test] test_usize_from_u32()38 fn test_usize_from_u32() { 39 assert_eq!(usize_from_u32(0), 0usize); 40 assert_eq!(usize_from_u32(u32::MAX), 4294967295usize); 41 } 42 } 43