Skip to content

Commit 6234610

Browse files
authored
Rollup merge of rust-lang#35058 - jethrogb:no_panic_abs, r=alexcrichton
Add non-panicking abs() functions to all signed integer types. Currently, calling abs() on one of the signed integer types might panic (in debug mode at least) because the absolute value of the largest negative value can not be represented in that signed type. Unlike all other integer operations, there is currently not a non-panicking version on this function. This seems to just be an oversight in the design, therefore just adding it now.
2 parents 96e3972 + cdc6afe commit 6234610

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

src/libcore/num/mod.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,31 @@ macro_rules! int_impl {
611611
if b {None} else {Some(a)}
612612
}
613613

614+
/// Checked absolute value. Computes `self.abs()`, returning `None` if
615+
/// `self == MIN`.
616+
///
617+
/// # Examples
618+
///
619+
/// Basic usage:
620+
///
621+
/// ```
622+
/// # #![feature(no_panic_abs)]
623+
///
624+
/// use std::i32;
625+
///
626+
/// assert_eq!((-5i32).checked_abs(), Some(5));
627+
/// assert_eq!(i32::MIN.checked_abs(), None);
628+
/// ```
629+
#[unstable(feature = "no_panic_abs", issue = "35057")]
630+
#[inline]
631+
pub fn checked_abs(self) -> Option<Self> {
632+
if self.is_negative() {
633+
self.checked_neg()
634+
} else {
635+
Some(self)
636+
}
637+
}
638+
614639
/// Saturating integer addition. Computes `self + other`, saturating at
615640
/// the numeric bounds instead of overflowing.
616641
///
@@ -863,6 +888,36 @@ macro_rules! int_impl {
863888
self.overflowing_shr(rhs).0
864889
}
865890

891+
/// Wrapping (modular) absolute value. Computes `self.abs()`,
892+
/// wrapping around at the boundary of the type.
893+
///
894+
/// The only case where such wrapping can occur is when one takes
895+
/// the absolute value of the negative minimal value for the type
896+
/// this is a positive value that is too large to represent in the
897+
/// type. In such a case, this function returns `MIN` itself.
898+
///
899+
/// # Examples
900+
///
901+
/// Basic usage:
902+
///
903+
/// ```
904+
/// # #![feature(no_panic_abs)]
905+
///
906+
/// assert_eq!(100i8.wrapping_abs(), 100);
907+
/// assert_eq!((-100i8).wrapping_abs(), 100);
908+
/// assert_eq!((-128i8).wrapping_abs(), -128);
909+
/// assert_eq!((-128i8).wrapping_abs() as u8, 128);
910+
/// ```
911+
#[unstable(feature = "no_panic_abs", issue = "35057")]
912+
#[inline(always)]
913+
pub fn wrapping_abs(self) -> Self {
914+
if self.is_negative() {
915+
self.wrapping_neg()
916+
} else {
917+
self
918+
}
919+
}
920+
866921
/// Calculates `self` + `rhs`
867922
///
868923
/// Returns a tuple of the addition along with a boolean indicating
@@ -1071,6 +1126,35 @@ macro_rules! int_impl {
10711126
(self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1)))
10721127
}
10731128

1129+
/// Computes the absolute value of `self`.
1130+
///
1131+
/// Returns a tuple of the absolute version of self along with a
1132+
/// boolean indicating whether an overflow happened. If self is the
1133+
/// minimum value (e.g. i32::MIN for values of type i32), then the
1134+
/// minimum value will be returned again and true will be returned for
1135+
/// an overflow happening.
1136+
///
1137+
/// # Examples
1138+
///
1139+
/// Basic usage:
1140+
///
1141+
/// ```
1142+
/// # #![feature(no_panic_abs)]
1143+
///
1144+
/// assert_eq!(10i8.overflowing_abs(), (10,false));
1145+
/// assert_eq!((-10i8).overflowing_abs(), (10,false));
1146+
/// assert_eq!((-128i8).overflowing_abs(), (-128,true));
1147+
/// ```
1148+
#[unstable(feature = "no_panic_abs", issue = "35057")]
1149+
#[inline]
1150+
pub fn overflowing_abs(self) -> (Self, bool) {
1151+
if self.is_negative() {
1152+
self.overflowing_neg()
1153+
} else {
1154+
(self, false)
1155+
}
1156+
}
1157+
10741158
/// Raises self to the power of `exp`, using exponentiation by squaring.
10751159
///
10761160
/// # Examples

0 commit comments

Comments
 (0)