1 | //! Definitions of `Saturating<T>`. |
2 | |
3 | use crate::fmt; |
4 | use crate::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign}; |
5 | use crate::ops::{BitXor, BitXorAssign, Div, DivAssign}; |
6 | use crate::ops::{Mul, MulAssign, Neg, Not, Rem, RemAssign}; |
7 | use crate::ops::{Sub, SubAssign}; |
8 | |
9 | /// Provides intentionally-saturating arithmetic on `T`. |
10 | /// |
11 | /// Operations like `+` on `u32` values are intended to never overflow, |
12 | /// and in some debug configurations overflow is detected and results |
13 | /// in a panic. While most arithmetic falls into this category, some |
14 | /// code explicitly expects and relies upon saturating arithmetic. |
15 | /// |
16 | /// Saturating arithmetic can be achieved either through methods like |
17 | /// `saturating_add`, or through the `Saturating<T>` type, which says that |
18 | /// all standard arithmetic operations on the underlying value are |
19 | /// intended to have saturating semantics. |
20 | /// |
21 | /// The underlying value can be retrieved through the `.0` index of the |
22 | /// `Saturating` tuple. |
23 | /// |
24 | /// # Examples |
25 | /// |
26 | /// ``` |
27 | /// use std::num::Saturating; |
28 | /// |
29 | /// let max = Saturating(u32::MAX); |
30 | /// let one = Saturating(1u32); |
31 | /// |
32 | /// assert_eq!(u32::MAX, (max + one).0); |
33 | /// ``` |
34 | #[stable (feature = "saturating_int_impl" , since = "1.74.0" )] |
35 | #[derive (PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)] |
36 | #[repr (transparent)] |
37 | #[rustc_diagnostic_item = "Saturating" ] |
38 | pub struct Saturating<T>(#[stable (feature = "saturating_int_impl" , since = "1.74.0" )] pub T); |
39 | |
40 | #[stable (feature = "saturating_int_impl" , since = "1.74.0" )] |
41 | impl<T: fmt::Debug> fmt::Debug for Saturating<T> { |
42 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
43 | self.0.fmt(f) |
44 | } |
45 | } |
46 | |
47 | #[stable (feature = "saturating_int_impl" , since = "1.74.0" )] |
48 | impl<T: fmt::Display> fmt::Display for Saturating<T> { |
49 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
50 | self.0.fmt(f) |
51 | } |
52 | } |
53 | |
54 | #[stable (feature = "saturating_int_impl" , since = "1.74.0" )] |
55 | impl<T: fmt::Binary> fmt::Binary for Saturating<T> { |
56 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
57 | self.0.fmt(f) |
58 | } |
59 | } |
60 | |
61 | #[stable (feature = "saturating_int_impl" , since = "1.74.0" )] |
62 | impl<T: fmt::Octal> fmt::Octal for Saturating<T> { |
63 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
64 | self.0.fmt(f) |
65 | } |
66 | } |
67 | |
68 | #[stable (feature = "saturating_int_impl" , since = "1.74.0" )] |
69 | impl<T: fmt::LowerHex> fmt::LowerHex for Saturating<T> { |
70 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
71 | self.0.fmt(f) |
72 | } |
73 | } |
74 | |
75 | #[stable (feature = "saturating_int_impl" , since = "1.74.0" )] |
76 | impl<T: fmt::UpperHex> fmt::UpperHex for Saturating<T> { |
77 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
78 | self.0.fmt(f) |
79 | } |
80 | } |
81 | |
82 | // FIXME the correct implementation is not clear. Waiting for a real world use case at https://github.com/rust-lang/libs-team/issues/230 |
83 | // |
84 | // #[allow(unused_macros)] |
85 | // macro_rules! sh_impl_signed { |
86 | // ($t:ident, $f:ident) => { |
87 | // // FIXME what is the correct implementation here? see discussion https://github.com/rust-lang/rust/pull/87921#discussion_r695870065 |
88 | // // |
89 | // // #[unstable(feature = "saturating_int_impl", issue = "87920")] |
90 | // // impl Shl<$f> for Saturating<$t> { |
91 | // // type Output = Saturating<$t>; |
92 | // // |
93 | // // #[inline] |
94 | // // fn shl(self, other: $f) -> Saturating<$t> { |
95 | // // if other < 0 { |
96 | // // Saturating(self.0.shr((-other & self::shift_max::$t as $f) as u32)) |
97 | // // } else { |
98 | // // Saturating(self.0.shl((other & self::shift_max::$t as $f) as u32)) |
99 | // // } |
100 | // // } |
101 | // // } |
102 | // // forward_ref_binop! { impl Shl, shl for Saturating<$t>, $f, |
103 | // // #[unstable(feature = "saturating_int_impl", issue = "87920")] } |
104 | // // |
105 | // // #[unstable(feature = "saturating_int_impl", issue = "87920")] |
106 | // // impl ShlAssign<$f> for Saturating<$t> { |
107 | // // #[inline] |
108 | // // fn shl_assign(&mut self, other: $f) { |
109 | // // *self = *self << other; |
110 | // // } |
111 | // // } |
112 | // // forward_ref_op_assign! { impl ShlAssign, shl_assign for Saturating<$t>, $f } |
113 | // |
114 | // #[unstable(feature = "saturating_int_impl", issue = "87920")] |
115 | // impl Shr<$f> for Saturating<$t> { |
116 | // type Output = Saturating<$t>; |
117 | // |
118 | // #[inline] |
119 | // fn shr(self, other: $f) -> Saturating<$t> { |
120 | // if other < 0 { |
121 | // Saturating(self.0.shl((-other & self::shift_max::$t as $f) as u32)) |
122 | // } else { |
123 | // Saturating(self.0.shr((other & self::shift_max::$t as $f) as u32)) |
124 | // } |
125 | // } |
126 | // } |
127 | // forward_ref_binop! { impl Shr, shr for Saturating<$t>, $f, |
128 | // #[unstable(feature = "saturating_int_impl", issue = "87920")] } |
129 | // |
130 | // #[unstable(feature = "saturating_int_impl", issue = "87920")] |
131 | // impl ShrAssign<$f> for Saturating<$t> { |
132 | // #[inline] |
133 | // fn shr_assign(&mut self, other: $f) { |
134 | // *self = *self >> other; |
135 | // } |
136 | // } |
137 | // forward_ref_op_assign! { impl ShrAssign, shr_assign for Saturating<$t>, $f } |
138 | // }; |
139 | // } |
140 | // |
141 | // macro_rules! sh_impl_unsigned { |
142 | // ($t:ident, $f:ident) => { |
143 | // #[unstable(feature = "saturating_int_impl", issue = "87920")] |
144 | // impl Shl<$f> for Saturating<$t> { |
145 | // type Output = Saturating<$t>; |
146 | // |
147 | // #[inline] |
148 | // fn shl(self, other: $f) -> Saturating<$t> { |
149 | // Saturating(self.0.wrapping_shl(other as u32)) |
150 | // } |
151 | // } |
152 | // forward_ref_binop! { impl Shl, shl for Saturating<$t>, $f, |
153 | // #[unstable(feature = "saturating_int_impl", issue = "87920")] } |
154 | // |
155 | // #[unstable(feature = "saturating_int_impl", issue = "87920")] |
156 | // impl ShlAssign<$f> for Saturating<$t> { |
157 | // #[inline] |
158 | // fn shl_assign(&mut self, other: $f) { |
159 | // *self = *self << other; |
160 | // } |
161 | // } |
162 | // forward_ref_op_assign! { impl ShlAssign, shl_assign for Saturating<$t>, $f } |
163 | // |
164 | // #[unstable(feature = "saturating_int_impl", issue = "87920")] |
165 | // impl Shr<$f> for Saturating<$t> { |
166 | // type Output = Saturating<$t>; |
167 | // |
168 | // #[inline] |
169 | // fn shr(self, other: $f) -> Saturating<$t> { |
170 | // Saturating(self.0.wrapping_shr(other as u32)) |
171 | // } |
172 | // } |
173 | // forward_ref_binop! { impl Shr, shr for Saturating<$t>, $f, |
174 | // #[unstable(feature = "saturating_int_impl", issue = "87920")] } |
175 | // |
176 | // #[unstable(feature = "saturating_int_impl", issue = "87920")] |
177 | // impl ShrAssign<$f> for Saturating<$t> { |
178 | // #[inline] |
179 | // fn shr_assign(&mut self, other: $f) { |
180 | // *self = *self >> other; |
181 | // } |
182 | // } |
183 | // forward_ref_op_assign! { impl ShrAssign, shr_assign for Saturating<$t>, $f } |
184 | // }; |
185 | // } |
186 | // |
187 | // // FIXME (#23545): uncomment the remaining impls |
188 | // macro_rules! sh_impl_all { |
189 | // ($($t:ident)*) => ($( |
190 | // //sh_impl_unsigned! { $t, u8 } |
191 | // //sh_impl_unsigned! { $t, u16 } |
192 | // //sh_impl_unsigned! { $t, u32 } |
193 | // //sh_impl_unsigned! { $t, u64 } |
194 | // //sh_impl_unsigned! { $t, u128 } |
195 | // sh_impl_unsigned! { $t, usize } |
196 | // |
197 | // //sh_impl_signed! { $t, i8 } |
198 | // //sh_impl_signed! { $t, i16 } |
199 | // //sh_impl_signed! { $t, i32 } |
200 | // //sh_impl_signed! { $t, i64 } |
201 | // //sh_impl_signed! { $t, i128 } |
202 | // //sh_impl_signed! { $t, isize } |
203 | // )*) |
204 | // } |
205 | // |
206 | // sh_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } |
207 | |
208 | // FIXME(30524): impl Op<T> for Saturating<T>, impl OpAssign<T> for Saturating<T> |
209 | macro_rules! saturating_impl { |
210 | ($($t:ty)*) => ($( |
211 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
212 | impl Add for Saturating<$t> { |
213 | type Output = Saturating<$t>; |
214 | |
215 | #[inline] |
216 | fn add(self, other: Saturating<$t>) -> Saturating<$t> { |
217 | Saturating(self.0.saturating_add(other.0)) |
218 | } |
219 | } |
220 | forward_ref_binop! { impl Add, add for Saturating<$t>, Saturating<$t>, |
221 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] } |
222 | |
223 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
224 | impl AddAssign for Saturating<$t> { |
225 | #[inline] |
226 | fn add_assign(&mut self, other: Saturating<$t>) { |
227 | *self = *self + other; |
228 | } |
229 | } |
230 | forward_ref_op_assign! { impl AddAssign, add_assign for Saturating<$t>, Saturating<$t> } |
231 | |
232 | #[stable(feature = "saturating_int_assign_impl" , since = "1.74.0" )] |
233 | impl AddAssign<$t> for Saturating<$t> { |
234 | #[inline] |
235 | fn add_assign(&mut self, other: $t) { |
236 | *self = *self + Saturating(other); |
237 | } |
238 | } |
239 | forward_ref_op_assign! { impl AddAssign, add_assign for Saturating<$t>, $t } |
240 | |
241 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
242 | impl Sub for Saturating<$t> { |
243 | type Output = Saturating<$t>; |
244 | |
245 | #[inline] |
246 | fn sub(self, other: Saturating<$t>) -> Saturating<$t> { |
247 | Saturating(self.0.saturating_sub(other.0)) |
248 | } |
249 | } |
250 | forward_ref_binop! { impl Sub, sub for Saturating<$t>, Saturating<$t>, |
251 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] } |
252 | |
253 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
254 | impl SubAssign for Saturating<$t> { |
255 | #[inline] |
256 | fn sub_assign(&mut self, other: Saturating<$t>) { |
257 | *self = *self - other; |
258 | } |
259 | } |
260 | forward_ref_op_assign! { impl SubAssign, sub_assign for Saturating<$t>, Saturating<$t> } |
261 | |
262 | #[stable(feature = "saturating_int_assign_impl" , since = "1.74.0" )] |
263 | impl SubAssign<$t> for Saturating<$t> { |
264 | #[inline] |
265 | fn sub_assign(&mut self, other: $t) { |
266 | *self = *self - Saturating(other); |
267 | } |
268 | } |
269 | forward_ref_op_assign! { impl SubAssign, sub_assign for Saturating<$t>, $t } |
270 | |
271 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
272 | impl Mul for Saturating<$t> { |
273 | type Output = Saturating<$t>; |
274 | |
275 | #[inline] |
276 | fn mul(self, other: Saturating<$t>) -> Saturating<$t> { |
277 | Saturating(self.0.saturating_mul(other.0)) |
278 | } |
279 | } |
280 | forward_ref_binop! { impl Mul, mul for Saturating<$t>, Saturating<$t>, |
281 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] } |
282 | |
283 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
284 | impl MulAssign for Saturating<$t> { |
285 | #[inline] |
286 | fn mul_assign(&mut self, other: Saturating<$t>) { |
287 | *self = *self * other; |
288 | } |
289 | } |
290 | forward_ref_op_assign! { impl MulAssign, mul_assign for Saturating<$t>, Saturating<$t> } |
291 | |
292 | #[stable(feature = "saturating_int_assign_impl" , since = "1.74.0" )] |
293 | impl MulAssign<$t> for Saturating<$t> { |
294 | #[inline] |
295 | fn mul_assign(&mut self, other: $t) { |
296 | *self = *self * Saturating(other); |
297 | } |
298 | } |
299 | forward_ref_op_assign! { impl MulAssign, mul_assign for Saturating<$t>, $t } |
300 | |
301 | /// # Examples |
302 | /// |
303 | /// Basic usage: |
304 | /// |
305 | /// ``` |
306 | /// use std::num::Saturating; |
307 | /// |
308 | #[doc = concat!("assert_eq!(Saturating(2" , stringify!($t), "), Saturating(5" , stringify!($t), ") / Saturating(2));" )] |
309 | #[doc = concat!("assert_eq!(Saturating(" , stringify!($t), "::MAX), Saturating(" , stringify!($t), "::MAX) / Saturating(1));" )] |
310 | #[doc = concat!("assert_eq!(Saturating(" , stringify!($t), "::MIN), Saturating(" , stringify!($t), "::MIN) / Saturating(1));" )] |
311 | /// ``` |
312 | /// |
313 | /// ```should_panic |
314 | /// use std::num::Saturating; |
315 | /// |
316 | #[doc = concat!("let _ = Saturating(0" , stringify!($t), ") / Saturating(0);" )] |
317 | /// ``` |
318 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
319 | impl Div for Saturating<$t> { |
320 | type Output = Saturating<$t>; |
321 | |
322 | #[inline] |
323 | fn div(self, other: Saturating<$t>) -> Saturating<$t> { |
324 | Saturating(self.0.saturating_div(other.0)) |
325 | } |
326 | } |
327 | forward_ref_binop! { impl Div, div for Saturating<$t>, Saturating<$t>, |
328 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] } |
329 | |
330 | |
331 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
332 | impl DivAssign for Saturating<$t> { |
333 | #[inline] |
334 | fn div_assign(&mut self, other: Saturating<$t>) { |
335 | *self = *self / other; |
336 | } |
337 | } |
338 | forward_ref_op_assign! { impl DivAssign, div_assign for Saturating<$t>, Saturating<$t> } |
339 | |
340 | #[stable(feature = "saturating_int_assign_impl" , since = "1.74.0" )] |
341 | impl DivAssign<$t> for Saturating<$t> { |
342 | #[inline] |
343 | fn div_assign(&mut self, other: $t) { |
344 | *self = *self / Saturating(other); |
345 | } |
346 | } |
347 | forward_ref_op_assign! { impl DivAssign, div_assign for Saturating<$t>, $t } |
348 | |
349 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
350 | impl Rem for Saturating<$t> { |
351 | type Output = Saturating<$t>; |
352 | |
353 | #[inline] |
354 | fn rem(self, other: Saturating<$t>) -> Saturating<$t> { |
355 | Saturating(self.0.rem(other.0)) |
356 | } |
357 | } |
358 | forward_ref_binop! { impl Rem, rem for Saturating<$t>, Saturating<$t>, |
359 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] } |
360 | |
361 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
362 | impl RemAssign for Saturating<$t> { |
363 | #[inline] |
364 | fn rem_assign(&mut self, other: Saturating<$t>) { |
365 | *self = *self % other; |
366 | } |
367 | } |
368 | forward_ref_op_assign! { impl RemAssign, rem_assign for Saturating<$t>, Saturating<$t> } |
369 | |
370 | #[stable(feature = "saturating_int_assign_impl" , since = "1.74.0" )] |
371 | impl RemAssign<$t> for Saturating<$t> { |
372 | #[inline] |
373 | fn rem_assign(&mut self, other: $t) { |
374 | *self = *self % Saturating(other); |
375 | } |
376 | } |
377 | forward_ref_op_assign! { impl RemAssign, rem_assign for Saturating<$t>, $t } |
378 | |
379 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
380 | impl Not for Saturating<$t> { |
381 | type Output = Saturating<$t>; |
382 | |
383 | #[inline] |
384 | fn not(self) -> Saturating<$t> { |
385 | Saturating(!self.0) |
386 | } |
387 | } |
388 | forward_ref_unop! { impl Not, not for Saturating<$t>, |
389 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] } |
390 | |
391 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
392 | impl BitXor for Saturating<$t> { |
393 | type Output = Saturating<$t>; |
394 | |
395 | #[inline] |
396 | fn bitxor(self, other: Saturating<$t>) -> Saturating<$t> { |
397 | Saturating(self.0 ^ other.0) |
398 | } |
399 | } |
400 | forward_ref_binop! { impl BitXor, bitxor for Saturating<$t>, Saturating<$t>, |
401 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] } |
402 | |
403 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
404 | impl BitXorAssign for Saturating<$t> { |
405 | #[inline] |
406 | fn bitxor_assign(&mut self, other: Saturating<$t>) { |
407 | *self = *self ^ other; |
408 | } |
409 | } |
410 | forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Saturating<$t>, Saturating<$t> } |
411 | |
412 | #[stable(feature = "saturating_int_assign_impl" , since = "1.74.0" )] |
413 | impl BitXorAssign<$t> for Saturating<$t> { |
414 | #[inline] |
415 | fn bitxor_assign(&mut self, other: $t) { |
416 | *self = *self ^ Saturating(other); |
417 | } |
418 | } |
419 | forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Saturating<$t>, $t } |
420 | |
421 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
422 | impl BitOr for Saturating<$t> { |
423 | type Output = Saturating<$t>; |
424 | |
425 | #[inline] |
426 | fn bitor(self, other: Saturating<$t>) -> Saturating<$t> { |
427 | Saturating(self.0 | other.0) |
428 | } |
429 | } |
430 | forward_ref_binop! { impl BitOr, bitor for Saturating<$t>, Saturating<$t>, |
431 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] } |
432 | |
433 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
434 | impl BitOrAssign for Saturating<$t> { |
435 | #[inline] |
436 | fn bitor_assign(&mut self, other: Saturating<$t>) { |
437 | *self = *self | other; |
438 | } |
439 | } |
440 | forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Saturating<$t>, Saturating<$t> } |
441 | |
442 | #[stable(feature = "saturating_int_assign_impl" , since = "1.74.0" )] |
443 | impl BitOrAssign<$t> for Saturating<$t> { |
444 | #[inline] |
445 | fn bitor_assign(&mut self, other: $t) { |
446 | *self = *self | Saturating(other); |
447 | } |
448 | } |
449 | forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Saturating<$t>, $t } |
450 | |
451 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
452 | impl BitAnd for Saturating<$t> { |
453 | type Output = Saturating<$t>; |
454 | |
455 | #[inline] |
456 | fn bitand(self, other: Saturating<$t>) -> Saturating<$t> { |
457 | Saturating(self.0 & other.0) |
458 | } |
459 | } |
460 | forward_ref_binop! { impl BitAnd, bitand for Saturating<$t>, Saturating<$t>, |
461 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] } |
462 | |
463 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
464 | impl BitAndAssign for Saturating<$t> { |
465 | #[inline] |
466 | fn bitand_assign(&mut self, other: Saturating<$t>) { |
467 | *self = *self & other; |
468 | } |
469 | } |
470 | forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Saturating<$t>, Saturating<$t> } |
471 | |
472 | #[stable(feature = "saturating_int_assign_impl" , since = "1.74.0" )] |
473 | impl BitAndAssign<$t> for Saturating<$t> { |
474 | #[inline] |
475 | fn bitand_assign(&mut self, other: $t) { |
476 | *self = *self & Saturating(other); |
477 | } |
478 | } |
479 | forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Saturating<$t>, $t } |
480 | |
481 | )*) |
482 | } |
483 | |
484 | saturating_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } |
485 | |
486 | macro_rules! saturating_int_impl { |
487 | ($($t:ty)*) => ($( |
488 | impl Saturating<$t> { |
489 | /// Returns the smallest value that can be represented by this integer type. |
490 | /// |
491 | /// # Examples |
492 | /// |
493 | /// Basic usage: |
494 | /// |
495 | /// ``` |
496 | /// use std::num::Saturating; |
497 | /// |
498 | #[doc = concat!("assert_eq!(<Saturating<" , stringify!($t), ">>::MIN, Saturating(" , stringify!($t), "::MIN));" )] |
499 | /// ``` |
500 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
501 | pub const MIN: Self = Self(<$t>::MIN); |
502 | |
503 | /// Returns the largest value that can be represented by this integer type. |
504 | /// |
505 | /// # Examples |
506 | /// |
507 | /// Basic usage: |
508 | /// |
509 | /// ``` |
510 | /// use std::num::Saturating; |
511 | /// |
512 | #[doc = concat!("assert_eq!(<Saturating<" , stringify!($t), ">>::MAX, Saturating(" , stringify!($t), "::MAX));" )] |
513 | /// ``` |
514 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
515 | pub const MAX: Self = Self(<$t>::MAX); |
516 | |
517 | /// Returns the size of this integer type in bits. |
518 | /// |
519 | /// # Examples |
520 | /// |
521 | /// Basic usage: |
522 | /// |
523 | /// ``` |
524 | /// use std::num::Saturating; |
525 | /// |
526 | #[doc = concat!("assert_eq!(<Saturating<" , stringify!($t), ">>::BITS, " , stringify!($t), "::BITS);" )] |
527 | /// ``` |
528 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
529 | pub const BITS: u32 = <$t>::BITS; |
530 | |
531 | /// Returns the number of ones in the binary representation of `self`. |
532 | /// |
533 | /// # Examples |
534 | /// |
535 | /// Basic usage: |
536 | /// |
537 | /// ``` |
538 | /// use std::num::Saturating; |
539 | /// |
540 | #[doc = concat!("let n = Saturating(0b01001100" , stringify!($t), ");" )] |
541 | /// |
542 | /// assert_eq!(n.count_ones(), 3); |
543 | /// ``` |
544 | #[inline] |
545 | #[doc(alias = "popcount" )] |
546 | #[doc(alias = "popcnt" )] |
547 | #[must_use = "this returns the result of the operation, \ |
548 | without modifying the original" ] |
549 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
550 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
551 | pub const fn count_ones(self) -> u32 { |
552 | self.0.count_ones() |
553 | } |
554 | |
555 | /// Returns the number of zeros in the binary representation of `self`. |
556 | /// |
557 | /// # Examples |
558 | /// |
559 | /// Basic usage: |
560 | /// |
561 | /// ``` |
562 | /// use std::num::Saturating; |
563 | /// |
564 | #[doc = concat!("assert_eq!(Saturating(!0" , stringify!($t), ").count_zeros(), 0);" )] |
565 | /// ``` |
566 | #[inline] |
567 | #[must_use = "this returns the result of the operation, \ |
568 | without modifying the original" ] |
569 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
570 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
571 | pub const fn count_zeros(self) -> u32 { |
572 | self.0.count_zeros() |
573 | } |
574 | |
575 | /// Returns the number of trailing zeros in the binary representation of `self`. |
576 | /// |
577 | /// # Examples |
578 | /// |
579 | /// Basic usage: |
580 | /// |
581 | /// ``` |
582 | /// use std::num::Saturating; |
583 | /// |
584 | #[doc = concat!("let n = Saturating(0b0101000" , stringify!($t), ");" )] |
585 | /// |
586 | /// assert_eq!(n.trailing_zeros(), 3); |
587 | /// ``` |
588 | #[inline] |
589 | #[must_use = "this returns the result of the operation, \ |
590 | without modifying the original" ] |
591 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
592 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
593 | pub const fn trailing_zeros(self) -> u32 { |
594 | self.0.trailing_zeros() |
595 | } |
596 | |
597 | /// Shifts the bits to the left by a specified amount, `n`, |
598 | /// saturating the truncated bits to the end of the resulting |
599 | /// integer. |
600 | /// |
601 | /// Please note this isn't the same operation as the `<<` shifting |
602 | /// operator! |
603 | /// |
604 | /// # Examples |
605 | /// |
606 | /// Basic usage: |
607 | /// |
608 | /// ``` |
609 | /// use std::num::Saturating; |
610 | /// |
611 | /// let n: Saturating<i64> = Saturating(0x0123456789ABCDEF); |
612 | /// let m: Saturating<i64> = Saturating(-0x76543210FEDCBA99); |
613 | /// |
614 | /// assert_eq!(n.rotate_left(32), m); |
615 | /// ``` |
616 | #[inline] |
617 | #[must_use = "this returns the result of the operation, \ |
618 | without modifying the original" ] |
619 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
620 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
621 | pub const fn rotate_left(self, n: u32) -> Self { |
622 | Saturating(self.0.rotate_left(n)) |
623 | } |
624 | |
625 | /// Shifts the bits to the right by a specified amount, `n`, |
626 | /// saturating the truncated bits to the beginning of the resulting |
627 | /// integer. |
628 | /// |
629 | /// Please note this isn't the same operation as the `>>` shifting |
630 | /// operator! |
631 | /// |
632 | /// # Examples |
633 | /// |
634 | /// Basic usage: |
635 | /// |
636 | /// ``` |
637 | /// use std::num::Saturating; |
638 | /// |
639 | /// let n: Saturating<i64> = Saturating(0x0123456789ABCDEF); |
640 | /// let m: Saturating<i64> = Saturating(-0xFEDCBA987654322); |
641 | /// |
642 | /// assert_eq!(n.rotate_right(4), m); |
643 | /// ``` |
644 | #[inline] |
645 | #[must_use = "this returns the result of the operation, \ |
646 | without modifying the original" ] |
647 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
648 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
649 | pub const fn rotate_right(self, n: u32) -> Self { |
650 | Saturating(self.0.rotate_right(n)) |
651 | } |
652 | |
653 | /// Reverses the byte order of the integer. |
654 | /// |
655 | /// # Examples |
656 | /// |
657 | /// Basic usage: |
658 | /// |
659 | /// ``` |
660 | /// use std::num::Saturating; |
661 | /// |
662 | /// let n: Saturating<i16> = Saturating(0b0000000_01010101); |
663 | /// assert_eq!(n, Saturating(85)); |
664 | /// |
665 | /// let m = n.swap_bytes(); |
666 | /// |
667 | /// assert_eq!(m, Saturating(0b01010101_00000000)); |
668 | /// assert_eq!(m, Saturating(21760)); |
669 | /// ``` |
670 | #[inline] |
671 | #[must_use = "this returns the result of the operation, \ |
672 | without modifying the original" ] |
673 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
674 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
675 | pub const fn swap_bytes(self) -> Self { |
676 | Saturating(self.0.swap_bytes()) |
677 | } |
678 | |
679 | /// Reverses the bit pattern of the integer. |
680 | /// |
681 | /// # Examples |
682 | /// |
683 | /// Please note that this example is shared between integer types. |
684 | /// Which explains why `i16` is used here. |
685 | /// |
686 | /// Basic usage: |
687 | /// |
688 | /// ``` |
689 | /// use std::num::Saturating; |
690 | /// |
691 | /// let n = Saturating(0b0000000_01010101i16); |
692 | /// assert_eq!(n, Saturating(85)); |
693 | /// |
694 | /// let m = n.reverse_bits(); |
695 | /// |
696 | /// assert_eq!(m.0 as u16, 0b10101010_00000000); |
697 | /// assert_eq!(m, Saturating(-22016)); |
698 | /// ``` |
699 | #[inline] |
700 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
701 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
702 | #[must_use = "this returns the result of the operation, \ |
703 | without modifying the original" ] |
704 | pub const fn reverse_bits(self) -> Self { |
705 | Saturating(self.0.reverse_bits()) |
706 | } |
707 | |
708 | /// Converts an integer from big endian to the target's endianness. |
709 | /// |
710 | /// On big endian this is a no-op. On little endian the bytes are |
711 | /// swapped. |
712 | /// |
713 | /// # Examples |
714 | /// |
715 | /// Basic usage: |
716 | /// |
717 | /// ``` |
718 | /// use std::num::Saturating; |
719 | /// |
720 | #[doc = concat!("let n = Saturating(0x1A" , stringify!($t), ");" )] |
721 | /// |
722 | /// if cfg!(target_endian = "big") { |
723 | #[doc = concat!(" assert_eq!(<Saturating<" , stringify!($t), ">>::from_be(n), n)" )] |
724 | /// } else { |
725 | #[doc = concat!(" assert_eq!(<Saturating<" , stringify!($t), ">>::from_be(n), n.swap_bytes())" )] |
726 | /// } |
727 | /// ``` |
728 | #[inline] |
729 | #[must_use] |
730 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
731 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
732 | pub const fn from_be(x: Self) -> Self { |
733 | Saturating(<$t>::from_be(x.0)) |
734 | } |
735 | |
736 | /// Converts an integer from little endian to the target's endianness. |
737 | /// |
738 | /// On little endian this is a no-op. On big endian the bytes are |
739 | /// swapped. |
740 | /// |
741 | /// # Examples |
742 | /// |
743 | /// Basic usage: |
744 | /// |
745 | /// ``` |
746 | /// use std::num::Saturating; |
747 | /// |
748 | #[doc = concat!("let n = Saturating(0x1A" , stringify!($t), ");" )] |
749 | /// |
750 | /// if cfg!(target_endian = "little") { |
751 | #[doc = concat!(" assert_eq!(<Saturating<" , stringify!($t), ">>::from_le(n), n)" )] |
752 | /// } else { |
753 | #[doc = concat!(" assert_eq!(<Saturating<" , stringify!($t), ">>::from_le(n), n.swap_bytes())" )] |
754 | /// } |
755 | /// ``` |
756 | #[inline] |
757 | #[must_use] |
758 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
759 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
760 | pub const fn from_le(x: Self) -> Self { |
761 | Saturating(<$t>::from_le(x.0)) |
762 | } |
763 | |
764 | /// Converts `self` to big endian from the target's endianness. |
765 | /// |
766 | /// On big endian this is a no-op. On little endian the bytes are |
767 | /// swapped. |
768 | /// |
769 | /// # Examples |
770 | /// |
771 | /// Basic usage: |
772 | /// |
773 | /// ``` |
774 | /// use std::num::Saturating; |
775 | /// |
776 | #[doc = concat!("let n = Saturating(0x1A" , stringify!($t), ");" )] |
777 | /// |
778 | /// if cfg!(target_endian = "big") { |
779 | /// assert_eq!(n.to_be(), n) |
780 | /// } else { |
781 | /// assert_eq!(n.to_be(), n.swap_bytes()) |
782 | /// } |
783 | /// ``` |
784 | #[inline] |
785 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
786 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
787 | #[must_use = "this returns the result of the operation, \ |
788 | without modifying the original" ] |
789 | pub const fn to_be(self) -> Self { |
790 | Saturating(self.0.to_be()) |
791 | } |
792 | |
793 | /// Converts `self` to little endian from the target's endianness. |
794 | /// |
795 | /// On little endian this is a no-op. On big endian the bytes are |
796 | /// swapped. |
797 | /// |
798 | /// # Examples |
799 | /// |
800 | /// Basic usage: |
801 | /// |
802 | /// ``` |
803 | /// use std::num::Saturating; |
804 | /// |
805 | #[doc = concat!("let n = Saturating(0x1A" , stringify!($t), ");" )] |
806 | /// |
807 | /// if cfg!(target_endian = "little") { |
808 | /// assert_eq!(n.to_le(), n) |
809 | /// } else { |
810 | /// assert_eq!(n.to_le(), n.swap_bytes()) |
811 | /// } |
812 | /// ``` |
813 | #[inline] |
814 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
815 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
816 | #[must_use = "this returns the result of the operation, \ |
817 | without modifying the original" ] |
818 | pub const fn to_le(self) -> Self { |
819 | Saturating(self.0.to_le()) |
820 | } |
821 | |
822 | /// Raises self to the power of `exp`, using exponentiation by squaring. |
823 | /// |
824 | /// # Examples |
825 | /// |
826 | /// Basic usage: |
827 | /// |
828 | /// ``` |
829 | /// use std::num::Saturating; |
830 | /// |
831 | #[doc = concat!("assert_eq!(Saturating(3" , stringify!($t), ").pow(4), Saturating(81));" )] |
832 | /// ``` |
833 | /// |
834 | /// Results that are too large are saturated: |
835 | /// |
836 | /// ``` |
837 | /// use std::num::Saturating; |
838 | /// |
839 | /// assert_eq!(Saturating(3i8).pow(5), Saturating(127)); |
840 | /// assert_eq!(Saturating(3i8).pow(6), Saturating(127)); |
841 | /// ``` |
842 | #[inline] |
843 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
844 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
845 | #[must_use = "this returns the result of the operation, \ |
846 | without modifying the original" ] |
847 | pub const fn pow(self, exp: u32) -> Self { |
848 | Saturating(self.0.saturating_pow(exp)) |
849 | } |
850 | } |
851 | )*) |
852 | } |
853 | |
854 | saturating_int_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } |
855 | |
856 | macro_rules! saturating_int_impl_signed { |
857 | ($($t:ty)*) => ($( |
858 | impl Saturating<$t> { |
859 | /// Returns the number of leading zeros in the binary representation of `self`. |
860 | /// |
861 | /// # Examples |
862 | /// |
863 | /// Basic usage: |
864 | /// |
865 | /// ``` |
866 | /// use std::num::Saturating; |
867 | /// |
868 | #[doc = concat!("let n = Saturating(" , stringify!($t), "::MAX >> 2);" )] |
869 | /// |
870 | /// assert_eq!(n.leading_zeros(), 3); |
871 | /// ``` |
872 | #[inline] |
873 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
874 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
875 | #[must_use = "this returns the result of the operation, \ |
876 | without modifying the original" ] |
877 | pub const fn leading_zeros(self) -> u32 { |
878 | self.0.leading_zeros() |
879 | } |
880 | |
881 | /// Saturating absolute value. Computes `self.abs()`, returning `MAX` if `self == MIN` |
882 | /// instead of overflowing. |
883 | /// |
884 | /// # Examples |
885 | /// |
886 | /// Basic usage: |
887 | /// |
888 | /// ``` |
889 | /// use std::num::Saturating; |
890 | /// |
891 | #[doc = concat!("assert_eq!(Saturating(100" , stringify!($t), ").abs(), Saturating(100));" )] |
892 | #[doc = concat!("assert_eq!(Saturating(-100" , stringify!($t), ").abs(), Saturating(100));" )] |
893 | #[doc = concat!("assert_eq!(Saturating(" , stringify!($t), "::MIN).abs(), Saturating((" , stringify!($t), "::MIN + 1).abs()));" )] |
894 | #[doc = concat!("assert_eq!(Saturating(" , stringify!($t), "::MIN).abs(), Saturating(" , stringify!($t), "::MIN.saturating_abs()));" )] |
895 | #[doc = concat!("assert_eq!(Saturating(" , stringify!($t), "::MIN).abs(), Saturating(" , stringify!($t), "::MAX));" )] |
896 | /// ``` |
897 | #[inline] |
898 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
899 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
900 | #[must_use = "this returns the result of the operation, \ |
901 | without modifying the original" ] |
902 | pub const fn abs(self) -> Saturating<$t> { |
903 | Saturating(self.0.saturating_abs()) |
904 | } |
905 | |
906 | /// Returns a number representing sign of `self`. |
907 | /// |
908 | /// - `0` if the number is zero |
909 | /// - `1` if the number is positive |
910 | /// - `-1` if the number is negative |
911 | /// |
912 | /// # Examples |
913 | /// |
914 | /// Basic usage: |
915 | /// |
916 | /// ``` |
917 | /// use std::num::Saturating; |
918 | /// |
919 | #[doc = concat!("assert_eq!(Saturating(10" , stringify!($t), ").signum(), Saturating(1));" )] |
920 | #[doc = concat!("assert_eq!(Saturating(0" , stringify!($t), ").signum(), Saturating(0));" )] |
921 | #[doc = concat!("assert_eq!(Saturating(-10" , stringify!($t), ").signum(), Saturating(-1));" )] |
922 | /// ``` |
923 | #[inline] |
924 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
925 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
926 | #[must_use = "this returns the result of the operation, \ |
927 | without modifying the original" ] |
928 | pub const fn signum(self) -> Saturating<$t> { |
929 | Saturating(self.0.signum()) |
930 | } |
931 | |
932 | /// Returns `true` if `self` is positive and `false` if the number is zero or |
933 | /// negative. |
934 | /// |
935 | /// # Examples |
936 | /// |
937 | /// Basic usage: |
938 | /// |
939 | /// ``` |
940 | /// use std::num::Saturating; |
941 | /// |
942 | #[doc = concat!("assert!(Saturating(10" , stringify!($t), ").is_positive());" )] |
943 | #[doc = concat!("assert!(!Saturating(-10" , stringify!($t), ").is_positive());" )] |
944 | /// ``` |
945 | #[must_use] |
946 | #[inline] |
947 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
948 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
949 | pub const fn is_positive(self) -> bool { |
950 | self.0.is_positive() |
951 | } |
952 | |
953 | /// Returns `true` if `self` is negative and `false` if the number is zero or |
954 | /// positive. |
955 | /// |
956 | /// # Examples |
957 | /// |
958 | /// Basic usage: |
959 | /// |
960 | /// ``` |
961 | /// use std::num::Saturating; |
962 | /// |
963 | #[doc = concat!("assert!(Saturating(-10" , stringify!($t), ").is_negative());" )] |
964 | #[doc = concat!("assert!(!Saturating(10" , stringify!($t), ").is_negative());" )] |
965 | /// ``` |
966 | #[must_use] |
967 | #[inline] |
968 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
969 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
970 | pub const fn is_negative(self) -> bool { |
971 | self.0.is_negative() |
972 | } |
973 | } |
974 | |
975 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
976 | impl Neg for Saturating<$t> { |
977 | type Output = Self; |
978 | #[inline] |
979 | fn neg(self) -> Self { |
980 | Saturating(self.0.saturating_neg()) |
981 | } |
982 | } |
983 | forward_ref_unop! { impl Neg, neg for Saturating<$t>, |
984 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] } |
985 | )*) |
986 | } |
987 | |
988 | saturating_int_impl_signed! { isize i8 i16 i32 i64 i128 } |
989 | |
990 | macro_rules! saturating_int_impl_unsigned { |
991 | ($($t:ty)*) => ($( |
992 | impl Saturating<$t> { |
993 | /// Returns the number of leading zeros in the binary representation of `self`. |
994 | /// |
995 | /// # Examples |
996 | /// |
997 | /// Basic usage: |
998 | /// |
999 | /// ``` |
1000 | /// use std::num::Saturating; |
1001 | /// |
1002 | #[doc = concat!("let n = Saturating(" , stringify!($t), "::MAX >> 2);" )] |
1003 | /// |
1004 | /// assert_eq!(n.leading_zeros(), 2); |
1005 | /// ``` |
1006 | #[inline] |
1007 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
1008 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
1009 | #[must_use = "this returns the result of the operation, \ |
1010 | without modifying the original" ] |
1011 | pub const fn leading_zeros(self) -> u32 { |
1012 | self.0.leading_zeros() |
1013 | } |
1014 | |
1015 | /// Returns `true` if and only if `self == 2^k` for some `k`. |
1016 | /// |
1017 | /// # Examples |
1018 | /// |
1019 | /// Basic usage: |
1020 | /// |
1021 | /// ``` |
1022 | /// use std::num::Saturating; |
1023 | /// |
1024 | #[doc = concat!("assert!(Saturating(16" , stringify!($t), ").is_power_of_two());" )] |
1025 | #[doc = concat!("assert!(!Saturating(10" , stringify!($t), ").is_power_of_two());" )] |
1026 | /// ``` |
1027 | #[must_use] |
1028 | #[inline] |
1029 | #[rustc_const_stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
1030 | #[stable(feature = "saturating_int_impl" , since = "1.74.0" )] |
1031 | pub const fn is_power_of_two(self) -> bool { |
1032 | self.0.is_power_of_two() |
1033 | } |
1034 | |
1035 | } |
1036 | )*) |
1037 | } |
1038 | |
1039 | saturating_int_impl_unsigned! { usize u8 u16 u32 u64 u128 } |
1040 | |
1041 | // Related to potential Shl and ShlAssign implementation |
1042 | // |
1043 | // mod shift_max { |
1044 | // #![allow(non_upper_case_globals)] |
1045 | // |
1046 | // #[cfg(target_pointer_width = "16")] |
1047 | // mod platform { |
1048 | // pub const usize: u32 = super::u16; |
1049 | // pub const isize: u32 = super::i16; |
1050 | // } |
1051 | // |
1052 | // #[cfg(target_pointer_width = "32")] |
1053 | // mod platform { |
1054 | // pub const usize: u32 = super::u32; |
1055 | // pub const isize: u32 = super::i32; |
1056 | // } |
1057 | // |
1058 | // #[cfg(target_pointer_width = "64")] |
1059 | // mod platform { |
1060 | // pub const usize: u32 = super::u64; |
1061 | // pub const isize: u32 = super::i64; |
1062 | // } |
1063 | // |
1064 | // pub const i8: u32 = (1 << 3) - 1; |
1065 | // pub const i16: u32 = (1 << 4) - 1; |
1066 | // pub const i32: u32 = (1 << 5) - 1; |
1067 | // pub const i64: u32 = (1 << 6) - 1; |
1068 | // pub const i128: u32 = (1 << 7) - 1; |
1069 | // pub use self::platform::isize; |
1070 | // |
1071 | // pub const u8: u32 = i8; |
1072 | // pub const u16: u32 = i16; |
1073 | // pub const u32: u32 = i32; |
1074 | // pub const u64: u32 = i64; |
1075 | // pub const u128: u32 = i128; |
1076 | // pub use self::platform::usize; |
1077 | // } |
1078 | |