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