1 use core::alloc::{Layout, LayoutErr};
2 use core::cmp;
3 use core::mem::{self, transmute};
4 #[cfg(feature = "std")]
5 use std::ffi::OsString;
6 #[cfg(feature = "std")]
7 use std::path::PathBuf;
8 
9 use crate::traits::{Float, Sealed};
10 
11 #[cfg(feature = "std")]
12 pub trait PathBuf_v1_44: Sealed<PathBuf> {
with_capacity(capacity: usize) -> PathBuf13     fn with_capacity(capacity: usize) -> PathBuf;
capacity(&self) -> usize14     fn capacity(&self) -> usize;
clear(&mut self)15     fn clear(&mut self);
reserve(&mut self, additional: usize)16     fn reserve(&mut self, additional: usize);
reserve_exact(&mut self, additional: usize)17     fn reserve_exact(&mut self, additional: usize);
shrink_to_fit(&mut self)18     fn shrink_to_fit(&mut self);
19 }
20 
21 #[cfg(feature = "std")]
22 impl PathBuf_v1_44 for PathBuf {
with_capacity(capacity: usize) -> PathBuf23     fn with_capacity(capacity: usize) -> PathBuf {
24         OsString::with_capacity(capacity).into()
25     }
26 
capacity(&self) -> usize27     fn capacity(&self) -> usize {
28         unsafe { transmute::<_, &OsString>(self) }.capacity()
29     }
30 
clear(&mut self)31     fn clear(&mut self) {
32         unsafe { transmute::<_, &mut OsString>(self) }.clear()
33     }
34 
reserve(&mut self, additional: usize)35     fn reserve(&mut self, additional: usize) {
36         unsafe { transmute::<_, &mut OsString>(self) }.reserve(additional)
37     }
38 
reserve_exact(&mut self, additional: usize)39     fn reserve_exact(&mut self, additional: usize) {
40         unsafe { transmute::<_, &mut OsString>(self) }.reserve_exact(additional)
41     }
42 
shrink_to_fit(&mut self)43     fn shrink_to_fit(&mut self) {
44         unsafe { transmute::<_, &mut OsString>(self) }.shrink_to_fit()
45     }
46 }
47 
48 pub trait Layout_v1_44: Sealed<Layout> {
align_to(&self, align: usize) -> Result<Layout, LayoutErr>49     fn align_to(&self, align: usize) -> Result<Layout, LayoutErr>;
pad_to_align(&self) -> Layout50     fn pad_to_align(&self) -> Layout;
array<T>(n: usize) -> Result<Layout, LayoutErr>51     fn array<T>(n: usize) -> Result<Layout, LayoutErr>;
extend(&self, next: Layout) -> Result<(Layout, usize), LayoutErr>52     fn extend(&self, next: Layout) -> Result<(Layout, usize), LayoutErr>;
53 }
54 
55 impl Layout_v1_44 for Layout {
56     #[inline]
align_to(&self, align: usize) -> Result<Self, LayoutErr>57     fn align_to(&self, align: usize) -> Result<Self, LayoutErr> {
58         Layout::from_size_align(self.size(), cmp::max(self.align(), align))
59     }
60 
61     #[inline]
pad_to_align(&self) -> Layout62     fn pad_to_align(&self) -> Layout {
63         let pad = padding_needed_for(self, self.align());
64         let new_size = self.size() + pad;
65         Layout::from_size_align(new_size, self.align()).unwrap()
66     }
67 
68     #[inline]
array<T>(n: usize) -> Result<Self, LayoutErr>69     fn array<T>(n: usize) -> Result<Self, LayoutErr> {
70         repeat(&Layout::new::<T>(), n).map(|(k, offs)| {
71             debug_assert!(offs == mem::size_of::<T>());
72             k
73         })
74     }
75 
76     #[inline]
extend(&self, next: Self) -> Result<(Self, usize), LayoutErr>77     fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
78         let new_align = cmp::max(self.align(), next.align());
79         let pad = padding_needed_for(self, next.align());
80 
81         let offset = self.size().checked_add(pad).ok_or(layout_err())?;
82         let new_size = offset.checked_add(next.size()).ok_or(layout_err())?;
83 
84         let layout = Layout::from_size_align(new_size, new_align)?;
85         Ok((layout, offset))
86     }
87 }
88 
padding_needed_for(zelf: &Layout, align: usize) -> usize89 fn padding_needed_for(zelf: &Layout, align: usize) -> usize {
90     let len = zelf.size();
91     let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
92     len_rounded_up.wrapping_sub(len)
93 }
94 
95 #[inline]
repeat(zelf: &Layout, n: usize) -> Result<(Layout, usize), LayoutErr>96 fn repeat(zelf: &Layout, n: usize) -> Result<(Layout, usize), LayoutErr> {
97     let padded_size = zelf.size() + padding_needed_for(zelf, zelf.align());
98     let alloc_size = padded_size.checked_mul(n).ok_or(layout_err())?;
99 
100     unsafe {
101         Ok((
102             Layout::from_size_align_unchecked(alloc_size, zelf.align()),
103             padded_size,
104         ))
105     }
106 }
107 
108 #[inline(always)]
layout_err() -> LayoutErr109 fn layout_err() -> LayoutErr {
110     unsafe { transmute(()) }
111 }
112 
113 mod sealed {
114     pub trait FloatToInt<Int> {
to_int_unchecked(self) -> Int115         unsafe fn to_int_unchecked(self) -> Int;
116     }
117 
118     macro_rules! impl_float_to_int {
119         ($float:ident => $($int:ident)+) => {$(
120             impl FloatToInt<$int> for $float {
121                 #[inline]
122                 unsafe fn to_int_unchecked(self) -> $int {
123                     self as $int
124                 }
125             }
126         )+}
127     }
128 
129     impl_float_to_int!(f32 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
130     impl_float_to_int!(f64 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
131 }
132 
133 pub trait float_v1_44: Float {
to_int_unchecked<Int>(self) -> Int where Self: sealed::FloatToInt<Int>134     unsafe fn to_int_unchecked<Int>(self) -> Int
135     where
136         Self: sealed::FloatToInt<Int>;
137 }
138 
139 impl float_v1_44 for f32 {
to_int_unchecked<Int>(self) -> Int where f32: sealed::FloatToInt<Int>,140     unsafe fn to_int_unchecked<Int>(self) -> Int
141     where
142         f32: sealed::FloatToInt<Int>,
143     {
144         sealed::FloatToInt::to_int_unchecked(self)
145     }
146 }
147 
148 impl float_v1_44 for f64 {
to_int_unchecked<Int>(self) -> Int where f64: sealed::FloatToInt<Int>,149     unsafe fn to_int_unchecked<Int>(self) -> Int
150     where
151         f64: sealed::FloatToInt<Int>,
152     {
153         sealed::FloatToInt::to_int_unchecked(self)
154     }
155 }
156