| use crate::traits::{Float, Sealed}; |
| use core::{ |
| alloc::{Layout, LayoutErr}, |
| cmp, |
| mem::{self, transmute}, |
| }; |
| #[cfg(feature = "std")] |
| use std::ffi::OsString; |
| #[cfg(feature = "std")] |
| use std::path::PathBuf; |
| |
| #[cfg(feature = "std")] |
| pub trait PathBuf_v1_44: Sealed<PathBuf> { |
| fn with_capacity(capacity: usize) -> PathBuf; |
| fn capacity(&self) -> usize; |
| fn clear(&mut self); |
| fn reserve(&mut self, additional: usize); |
| fn reserve_exact(&mut self, additional: usize); |
| fn shrink_to_fit(&mut self); |
| } |
| |
| #[cfg(feature = "std")] |
| impl PathBuf_v1_44 for PathBuf { |
| fn with_capacity(capacity: usize) -> PathBuf { |
| OsString::with_capacity(capacity).into() |
| } |
| |
| fn capacity(&self) -> usize { |
| unsafe { transmute::<_, &OsString>(self) }.capacity() |
| } |
| |
| fn clear(&mut self) { |
| unsafe { transmute::<_, &mut OsString>(self) }.clear() |
| } |
| |
| fn reserve(&mut self, additional: usize) { |
| unsafe { transmute::<_, &mut OsString>(self) }.reserve(additional) |
| } |
| |
| fn reserve_exact(&mut self, additional: usize) { |
| unsafe { transmute::<_, &mut OsString>(self) }.reserve_exact(additional) |
| } |
| |
| fn shrink_to_fit(&mut self) { |
| unsafe { transmute::<_, &mut OsString>(self) }.shrink_to_fit() |
| } |
| } |
| |
| pub trait Layout_v1_44: Sealed<Layout> { |
| fn align_to(&self, align: usize) -> Result<Layout, LayoutErr>; |
| fn pad_to_align(&self) -> Layout; |
| fn array<T>(n: usize) -> Result<Layout, LayoutErr>; |
| fn extend(&self, next: Layout) -> Result<(Layout, usize), LayoutErr>; |
| } |
| |
| impl Layout_v1_44 for Layout { |
| #[inline] |
| fn align_to(&self, align: usize) -> Result<Self, LayoutErr> { |
| Layout::from_size_align(self.size(), cmp::max(self.align(), align)) |
| } |
| |
| #[inline] |
| fn pad_to_align(&self) -> Layout { |
| let pad = padding_needed_for(self, self.align()); |
| let new_size = self.size() + pad; |
| Layout::from_size_align(new_size, self.align()).unwrap() |
| } |
| |
| #[inline] |
| fn array<T>(n: usize) -> Result<Self, LayoutErr> { |
| repeat(&Layout::new::<T>(), n).map(|(k, offs)| { |
| debug_assert!(offs == mem::size_of::<T>()); |
| k |
| }) |
| } |
| |
| #[inline] |
| fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> { |
| let new_align = cmp::max(self.align(), next.align()); |
| let pad = padding_needed_for(self, next.align()); |
| |
| let offset = self.size().checked_add(pad).ok_or(layout_err())?; |
| let new_size = offset.checked_add(next.size()).ok_or(layout_err())?; |
| |
| let layout = Layout::from_size_align(new_size, new_align)?; |
| Ok((layout, offset)) |
| } |
| } |
| |
| fn padding_needed_for(zelf: &Layout, align: usize) -> usize { |
| let len = zelf.size(); |
| let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1); |
| len_rounded_up.wrapping_sub(len) |
| } |
| |
| #[inline] |
| fn repeat(zelf: &Layout, n: usize) -> Result<(Layout, usize), LayoutErr> { |
| let padded_size = zelf.size() + padding_needed_for(zelf, zelf.align()); |
| let alloc_size = padded_size.checked_mul(n).ok_or(layout_err())?; |
| |
| unsafe { |
| Ok(( |
| Layout::from_size_align_unchecked(alloc_size, zelf.align()), |
| padded_size, |
| )) |
| } |
| } |
| |
| #[inline(always)] |
| fn layout_err() -> LayoutErr { |
| // We can safely transmute this, as zero-sized types have no actual memory |
| // representation. If `LayoutErr` ever has the addition of a field, this |
| // will stop compiling (rather than creating undefined behavior). |
| unsafe { transmute(()) } |
| } |
| |
| mod sealed { |
| pub trait FloatToInt<Int> { |
| unsafe fn to_int_unchecked(self) -> Int; |
| } |
| |
| macro_rules! impl_float_to_int { |
| ($float:ident => $($int:ident)+) => {$( |
| impl FloatToInt<$int> for $float { |
| #[inline] |
| unsafe fn to_int_unchecked(self) -> $int { |
| self as $int |
| } |
| } |
| )+} |
| } |
| |
| impl_float_to_int!(f32 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize); |
| impl_float_to_int!(f64 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize); |
| } |
| |
| pub trait float_v1_44: Float { |
| unsafe fn to_int_unchecked<Int>(self) -> Int |
| where |
| Self: sealed::FloatToInt<Int>; |
| } |
| |
| impl float_v1_44 for f32 { |
| unsafe fn to_int_unchecked<Int>(self) -> Int |
| where |
| f32: sealed::FloatToInt<Int>, |
| { |
| sealed::FloatToInt::to_int_unchecked(self) |
| } |
| } |
| |
| impl float_v1_44 for f64 { |
| unsafe fn to_int_unchecked<Int>(self) -> Int |
| where |
| f64: sealed::FloatToInt<Int>, |
| { |
| sealed::FloatToInt::to_int_unchecked(self) |
| } |
| } |