1 use crate::{Float, Integer, Sealed}; 2 use core::time::Duration; 3 4 pub trait ConstPtr_v1_38<T>: Sealed<*const T> { cast<U>(self) -> *const U5 fn cast<U>(self) -> *const U; 6 } 7 8 impl<T> ConstPtr_v1_38<T> for *const T { 9 #[inline] cast<U>(self) -> *const U10 fn cast<U>(self) -> *const U { 11 self as _ 12 } 13 } 14 15 pub trait MutPtr_v1_38<T>: Sealed<*mut T> { cast<U>(self) -> *mut U16 fn cast<U>(self) -> *mut U; 17 } 18 19 impl<T> MutPtr_v1_38<T> for *mut T { 20 #[inline] cast<U>(self) -> *mut U21 fn cast<U>(self) -> *mut U { 22 self as _ 23 } 24 } 25 26 pub trait Duration_v1_38: Sealed<Duration> { as_secs_f32(&self) -> f3227 fn as_secs_f32(&self) -> f32; as_secs_f64(&self) -> f6428 fn as_secs_f64(&self) -> f64; div_f32(&self, rhs: f32) -> Self29 fn div_f32(&self, rhs: f32) -> Self; div_f64(&self, rhs: f64) -> Self30 fn div_f64(&self, rhs: f64) -> Self; from_secs_f32(secs: f32) -> Self31 fn from_secs_f32(secs: f32) -> Self; from_secs_f64(secs: f64) -> Self32 fn from_secs_f64(secs: f64) -> Self; mul_f32(&self, rhs: f32) -> Self33 fn mul_f32(&self, rhs: f32) -> Self; mul_f64(&self, rhs: f64) -> Self34 fn mul_f64(&self, rhs: f64) -> Self; 35 } 36 37 impl Duration_v1_38 for Duration { 38 #[inline] as_secs_f32(&self) -> f3239 fn as_secs_f32(&self) -> f32 { 40 (self.as_secs() as f32) + (self.subsec_nanos() as f32) / 1_000_000_000. 41 } 42 43 #[inline] as_secs_f64(&self) -> f6444 fn as_secs_f64(&self) -> f64 { 45 (self.as_secs() as f64) + (self.subsec_nanos() as f64) / 1_000_000_000. 46 } 47 48 #[inline] div_f32(&self, rhs: f32) -> Self49 fn div_f32(&self, rhs: f32) -> Self { 50 Self::from_secs_f32(self.as_secs_f32() / rhs) 51 } 52 53 #[inline] div_f64(&self, rhs: f64) -> Self54 fn div_f64(&self, rhs: f64) -> Self { 55 Self::from_secs_f64(self.as_secs_f64() / rhs) 56 } 57 58 #[inline] from_secs_f32(secs: f32) -> Self59 fn from_secs_f32(secs: f32) -> Self { 60 const MAX_NANOS_F32: f32 = ((u64::max_value() as u128 + 1) * 1_000_000_000) as f32; 61 let nanos = secs * 1_000_000_000.; 62 if !nanos.is_finite() { 63 panic!("got non-finite value when converting float to duration"); 64 } 65 if nanos >= MAX_NANOS_F32 { 66 panic!("overflow when converting float to duration"); 67 } 68 if nanos < 0.0 { 69 panic!("underflow when converting float to duration"); 70 } 71 let nanos = nanos as u128; 72 Self::new( 73 (nanos / 1_000_000_000) as u64, 74 (nanos % 1_000_000_000) as u32, 75 ) 76 } 77 78 #[inline] from_secs_f64(secs: f64) -> Self79 fn from_secs_f64(secs: f64) -> Self { 80 const MAX_NANOS_F64: f64 = ((u64::max_value() as u128 + 1) * 1_000_000_000) as f64; 81 let nanos = secs * 1_000_000_000.; 82 if !nanos.is_finite() { 83 panic!("got non-finite value when converting float to duration"); 84 } 85 if nanos >= MAX_NANOS_F64 { 86 panic!("overflow when converting float to duration"); 87 } 88 if nanos < 0.0 { 89 panic!("underflow when converting float to duration"); 90 } 91 let nanos = nanos as u128; 92 Self::new( 93 (nanos / 1_000_000_000) as u64, 94 (nanos % 1_000_000_000) as u32, 95 ) 96 } 97 98 #[inline] mul_f32(&self, rhs: f32) -> Self99 fn mul_f32(&self, rhs: f32) -> Self { 100 Self::from_secs_f32(rhs * self.as_secs_f32()) 101 } 102 103 #[inline] mul_f64(&self, rhs: f64) -> Self104 fn mul_f64(&self, rhs: f64) -> Self { 105 Self::from_secs_f64(rhs * self.as_secs_f64()) 106 } 107 } 108 109 pub trait Euclid_v1_38: Integer { rem_euclid(self, rhs: Self) -> Self110 fn rem_euclid(self, rhs: Self) -> Self; checked_rem_euclid(self, rhs: Self) -> Option<Self>111 fn checked_rem_euclid(self, rhs: Self) -> Option<Self>; wrapping_rem_euclid(self, rhs: Self) -> Self112 fn wrapping_rem_euclid(self, rhs: Self) -> Self; overflowing_rem_euclid(self, rhs: Self) -> (Self, bool)113 fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool); div_euclid(self, rhs: Self) -> Self114 fn div_euclid(self, rhs: Self) -> Self; checked_div_euclid(self, rhs: Self) -> Option<Self>115 fn checked_div_euclid(self, rhs: Self) -> Option<Self>; wrapping_div_euclid(self, rhs: Self) -> Self116 fn wrapping_div_euclid(self, rhs: Self) -> Self; overflowing_div_euclid(self, rhs: Self) -> (Self, bool)117 fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool); 118 } 119 120 macro_rules! impl_euclid_for_signed { 121 ($($type:ty)+) => {$( 122 impl Euclid_v1_38 for $type { 123 #[must_use = "this returns the result of the operation, without modifying the original"] 124 #[inline] 125 fn rem_euclid(self, rhs: Self) -> Self { 126 let r = self % rhs; 127 if r < 0 { 128 if rhs < 0 { 129 r - rhs 130 } else { 131 r + rhs 132 } 133 } else { 134 r 135 } 136 } 137 138 #[must_use = "this returns the result of the operation, without modifying the original"] 139 #[inline] 140 fn checked_rem_euclid(self, rhs: Self) -> Option<Self> { 141 if rhs == 0 || (self == Self::min_value() && rhs == -1) { 142 None 143 } else { 144 Some(self.rem_euclid(rhs)) 145 } 146 } 147 148 #[must_use = "this returns the result of the operation, without modifying the original"] 149 #[inline] 150 fn wrapping_rem_euclid(self, rhs: Self) -> Self { 151 self.overflowing_rem_euclid(rhs).0 152 } 153 154 #[must_use = "this returns the result of the operation, without modifying the original"] 155 #[inline] 156 fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { 157 if self == Self::min_value() && rhs == -1 { 158 (0, true) 159 } else { 160 (self.rem_euclid(rhs), false) 161 } 162 } 163 164 #[must_use = "this returns the result of the operation, without modifying the original"] 165 #[inline] 166 fn div_euclid(self, rhs: Self) -> Self { 167 let q = self / rhs; 168 if self % rhs < 0 { 169 return if rhs > 0 { q - 1 } else { q + 1 }; 170 } 171 q 172 } 173 174 #[must_use = "this returns the result of the operation, without modifying the original"] 175 #[inline] 176 fn checked_div_euclid(self, rhs: Self) -> Option<Self> { 177 if rhs == 0 || (self == Self::min_value() && rhs == -1) { 178 None 179 } else { 180 Some(self.div_euclid(rhs)) 181 } 182 } 183 184 #[must_use = "this returns the result of the operation, without modifying the original"] 185 #[inline] 186 fn wrapping_div_euclid(self, rhs: Self) -> Self { 187 self.overflowing_div_euclid(rhs).0 188 } 189 190 #[must_use = "this returns the result of the operation, without modifying the original"] 191 #[inline] 192 fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { 193 if self == Self::min_value() && rhs == -1 { 194 (self, true) 195 } else { 196 (self.div_euclid(rhs), false) 197 } 198 } 199 } 200 )+}; 201 } 202 203 impl_euclid_for_signed![i8 i16 i32 i64 i128 isize]; 204 205 macro_rules! impl_euclid_for_unsigned { 206 ($($type:ty)+) => {$( 207 impl Euclid_v1_38 for $type { 208 #[must_use = "this returns the result of the operation, without modifying the original"] 209 #[inline] 210 fn rem_euclid(self, rhs: Self) -> Self { 211 self % rhs 212 } 213 214 #[must_use = "this returns the result of the operation, without modifying the original"] 215 #[inline] 216 fn checked_rem_euclid(self, rhs: Self) -> Option<Self> { 217 if rhs == 0 { 218 None 219 } else { 220 Some(self.rem_euclid(rhs)) 221 } 222 } 223 224 #[must_use = "this returns the result of the operation, without modifying the original"] 225 #[inline] 226 fn wrapping_rem_euclid(self, rhs: Self) -> Self { 227 self % rhs 228 } 229 230 #[must_use = "this returns the result of the operation, without modifying the original"] 231 #[inline] 232 fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { 233 (self % rhs, false) 234 } 235 236 #[must_use = "this returns the result of the operation, without modifying the original"] 237 #[inline] 238 fn div_euclid(self, rhs: Self) -> Self { 239 self / rhs 240 } 241 242 #[must_use = "this returns the result of the operation, without modifying the original"] 243 #[inline] 244 fn checked_div_euclid(self, rhs: Self) -> Option<Self> { 245 if rhs == 0 { 246 None 247 } else { 248 Some(self.div_euclid(rhs)) 249 } 250 } 251 252 #[must_use = "this returns the result of the operation, without modifying the original"] 253 #[inline] 254 fn wrapping_div_euclid(self, rhs: Self) -> Self { 255 self / rhs 256 } 257 258 #[must_use = "this returns the result of the operation, without modifying the original"] 259 #[inline] 260 fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { 261 (self / rhs, false) 262 } 263 } 264 )+}; 265 } 266 267 impl_euclid_for_unsigned![u8 u16 u32 u64 u128 usize]; 268 269 pub trait EuclidFloat_v1_38: Float { rem_euclid(self, rhs: Self) -> Self270 fn rem_euclid(self, rhs: Self) -> Self; div_euclid(self, rhs: Self) -> Self271 fn div_euclid(self, rhs: Self) -> Self; 272 } 273 274 #[cfg(std)] 275 impl EuclidFloat_v1_38 for f32 { 276 #[must_use = "method returns a new number and does not mutate the original value"] 277 #[inline] rem_euclid(self, rhs: f32) -> f32278 fn rem_euclid(self, rhs: f32) -> f32 { 279 let r = self % rhs; 280 if r < 0.0 { 281 r + rhs.abs() 282 } else { 283 r 284 } 285 } 286 287 #[must_use = "method returns a new number and does not mutate the original value"] 288 #[inline] div_euclid(self, rhs: f32) -> f32289 fn div_euclid(self, rhs: f32) -> f32 { 290 let q = (self / rhs).trunc(); 291 if self % rhs < 0.0 { 292 return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }; 293 } 294 q 295 } 296 } 297 298 #[cfg(std)] 299 impl EuclidFloat_v1_38 for f64 { 300 #[must_use = "method returns a new number and does not mutate the original value"] 301 #[inline] rem_euclid(self, rhs: f64) -> f64302 fn rem_euclid(self, rhs: f64) -> f64 { 303 let r = self % rhs; 304 if r < 0.0 { 305 r + rhs.abs() 306 } else { 307 r 308 } 309 } 310 311 #[must_use = "method returns a new number and does not mutate the original value"] 312 #[inline] div_euclid(self, rhs: f64) -> f64313 fn div_euclid(self, rhs: f64) -> f64 { 314 let q = (self / rhs).trunc(); 315 if self % rhs < 0.0 { 316 return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }; 317 } 318 q 319 } 320 } 321