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
/// A trait which is only implemented for pointers for which the length of the pointee /// can be determined without creating a reference to the pointee and without accessing /// the pointee. This means that the pointer is not dereferenced. /// /// # Example /// ``` /// use deferred_reference::PointerLength; /// let array = [0usize; 1024]; /// assert_eq!(1024, PointerLength::len(core::ptr::addr_of!(array))); /// ``` /// /// # Safety /// This trait is unsafe. The implementor must promise never to access or create a reference /// to the pointee. pub unsafe trait PointerLength { /// Obtains the length of the pointee, without creating an intermediate reference. fn len(ptr: *const Self) -> usize; } // SAFETY: <*const [T]>::len() extracts the length from the fat pointer without // SAFETY: dereferencing the pointer, so this is safe. #[cfg(feature = "slice_ptr_len")] unsafe impl<T> PointerLength for [T] { #[inline] fn len(ptr: *const Self) -> usize { // requires #![feature(slice_ptr_len)] at crate level <*const [T]>::len(ptr) } } // SAFETY: this impl does not create any references, it merely panics #[cfg(not(feature = "slice_ptr_len"))] unsafe impl<T> PointerLength for [T] { #[track_caller] #[cold] fn len(_: *const Self) -> usize { // without the `slice_ptr_len` feature, all we can do is panic in order to keep the implementation sound. panic!("calling this method on slice pointers requires the `slice_ptr_len` feature to be enabled") } } // SAFETY: the array length is known at compile time due to the `const N: usize`. // SAFETY: the pointer is not needed nor dereferenced when returning a constant. unsafe impl <T, const N: usize> PointerLength for [T; N] { #[inline] fn len(_: *const Self) -> usize { N } }