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