Skip to content

Commit 4991c7a

Browse files
committed
Remaining API additions for int overflow:
`wrapping_div`, `wrapping_rem`, `wrapping_neg`, `wrapping_shl`, `wrapping_shr`. All marked unstable under `core` feature for now (with expectation of being marked as stable by 1.0 release).
1 parent a9d8065 commit 4991c7a

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

Diff for: src/libcore/num/mod.rs

+120
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,66 @@ macro_rules! int_impl {
12191219
}
12201220
}
12211221

1222+
/// Wrapping (modular) division. Computes `floor(self / other)`,
1223+
/// wrapping around at the boundary of the type.
1224+
///
1225+
/// The only case where such wrapping can occur is when one
1226+
/// divides `MIN / -1` on a signed type (where `MIN` is the
1227+
/// negative minimal value for the type); this is equivalent
1228+
/// to `-MIN`, a positive value that is too large to represent
1229+
/// in the type. In such a case, this function returns `MIN`
1230+
/// itself..
1231+
#[unstable(feature = "core", since = "1.0.0")]
1232+
#[inline(always)]
1233+
pub fn wrapping_div(self, rhs: $T) -> $T {
1234+
self.overflowing_div(rhs).0
1235+
}
1236+
1237+
/// Wrapping (modular) remainder. Computes `self % other`,
1238+
/// wrapping around at the boundary of the type.
1239+
///
1240+
/// Such wrap-around never actually occurs mathematically;
1241+
/// implementation artifacts make `x % y` illegal for `MIN /
1242+
/// -1` on a signed type illegal (where `MIN` is the negative
1243+
/// minimal value). In such a case, this function returns `0`.
1244+
#[unstable(feature = "core", since = "1.0.0")]
1245+
#[inline(always)]
1246+
pub fn wrapping_rem(self, rhs: $T) -> $T {
1247+
self.overflowing_rem(rhs).0
1248+
}
1249+
1250+
/// Wrapping (modular) negation. Computes `-self`,
1251+
/// wrapping around at the boundary of the type.
1252+
///
1253+
/// The only case where such wrapping can occur is when one
1254+
/// negates `MIN` on a signed type (where `MIN` is the
1255+
/// negative minimal value for the type); this is a positive
1256+
/// value that is too large to represent in the type. In such
1257+
/// a case, this function returns `MIN` itself.
1258+
#[unstable(feature = "core", since = "1.0.0")]
1259+
#[inline(always)]
1260+
pub fn wrapping_neg(self) -> $T {
1261+
self.overflowing_neg().0
1262+
}
1263+
1264+
/// Panic-free bitwise shift-left; yields `self << mask(rhs)`,
1265+
/// where `mask` removes any high-order bits of `rhs` that
1266+
/// would cause the shift to exceed the bitwidth of the type.
1267+
#[unstable(feature = "core", since = "1.0.0")]
1268+
#[inline(always)]
1269+
pub fn wrapping_shl(self, rhs: u32) -> $T {
1270+
self.overflowing_shl(rhs).0
1271+
}
1272+
1273+
/// Panic-free bitwise shift-left; yields `self >> mask(rhs)`,
1274+
/// where `mask` removes any high-order bits of `rhs` that
1275+
/// would cause the shift to exceed the bitwidth of the type.
1276+
#[unstable(feature = "core", since = "1.0.0")]
1277+
#[inline(always)]
1278+
pub fn wrapping_shr(self, rhs: u32) -> $T {
1279+
self.overflowing_shr(rhs).0
1280+
}
1281+
12221282
/// Raises self to the power of `exp`, using exponentiation by squaring.
12231283
///
12241284
/// # Examples
@@ -1739,6 +1799,66 @@ macro_rules! uint_impl {
17391799
}
17401800
}
17411801

1802+
/// Wrapping (modular) division. Computes `floor(self / other)`,
1803+
/// wrapping around at the boundary of the type.
1804+
///
1805+
/// The only case where such wrapping can occur is when one
1806+
/// divides `MIN / -1` on a signed type (where `MIN` is the
1807+
/// negative minimal value for the type); this is equivalent
1808+
/// to `-MIN`, a positive value that is too large to represent
1809+
/// in the type. In such a case, this function returns `MIN`
1810+
/// itself..
1811+
#[unstable(feature = "core", since = "1.0.0")]
1812+
#[inline(always)]
1813+
pub fn wrapping_div(self, rhs: $T) -> $T {
1814+
self.overflowing_div(rhs).0
1815+
}
1816+
1817+
/// Wrapping (modular) remainder. Computes `self % other`,
1818+
/// wrapping around at the boundary of the type.
1819+
///
1820+
/// Such wrap-around never actually occurs mathematically;
1821+
/// implementation artifacts make `x % y` illegal for `MIN /
1822+
/// -1` on a signed type illegal (where `MIN` is the negative
1823+
/// minimal value). In such a case, this function returns `0`.
1824+
#[unstable(feature = "core", since = "1.0.0")]
1825+
#[inline(always)]
1826+
pub fn wrapping_rem(self, rhs: $T) -> $T {
1827+
self.overflowing_rem(rhs).0
1828+
}
1829+
1830+
/// Wrapping (modular) negation. Computes `-self`,
1831+
/// wrapping around at the boundary of the type.
1832+
///
1833+
/// The only case where such wrapping can occur is when one
1834+
/// negates `MIN` on a signed type (where `MIN` is the
1835+
/// negative minimal value for the type); this is a positive
1836+
/// value that is too large to represent in the type. In such
1837+
/// a case, this function returns `MIN` itself.
1838+
#[unstable(feature = "core", since = "1.0.0")]
1839+
#[inline(always)]
1840+
pub fn wrapping_neg(self) -> $T {
1841+
self.overflowing_neg().0
1842+
}
1843+
1844+
/// Panic-free bitwise shift-left; yields `self << mask(rhs)`,
1845+
/// where `mask` removes any high-order bits of `rhs` that
1846+
/// would cause the shift to exceed the bitwidth of the type.
1847+
#[unstable(feature = "core", since = "1.0.0")]
1848+
#[inline(always)]
1849+
pub fn wrapping_shl(self, rhs: u32) -> $T {
1850+
self.overflowing_shl(rhs).0
1851+
}
1852+
1853+
/// Panic-free bitwise shift-left; yields `self >> mask(rhs)`,
1854+
/// where `mask` removes any high-order bits of `rhs` that
1855+
/// would cause the shift to exceed the bitwidth of the type.
1856+
#[unstable(feature = "core", since = "1.0.0")]
1857+
#[inline(always)]
1858+
pub fn wrapping_shr(self, rhs: u32) -> $T {
1859+
self.overflowing_shr(rhs).0
1860+
}
1861+
17421862
/// Raises self to the power of `exp`, using exponentiation by squaring.
17431863
///
17441864
/// # Examples

Diff for: src/libcore/num/wrapping.rs

+35
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub trait OverflowingOps {
4848

4949
fn overflowing_div(self, rhs: Self) -> (Self, bool);
5050
fn overflowing_rem(self, rhs: Self) -> (Self, bool);
51+
fn overflowing_neg(self) -> (Self, bool);
5152

5253
fn overflowing_shl(self, rhs: u32) -> (Self, bool);
5354
fn overflowing_shr(self, rhs: u32) -> (Self, bool);
@@ -255,6 +256,15 @@ macro_rules! signed_overflowing_impl {
255256
(self >> (rhs & self::shift_max::$t),
256257
(rhs > self::shift_max::$t))
257258
}
259+
260+
#[inline(always)]
261+
fn overflowing_neg(self) -> ($t, bool) {
262+
if self == $t::MIN {
263+
($t::MIN, true)
264+
} else {
265+
(-self, false)
266+
}
267+
}
258268
}
259269
)*)
260270
}
@@ -300,6 +310,11 @@ macro_rules! unsigned_overflowing_impl {
300310
(self >> (rhs & self::shift_max::$t),
301311
(rhs > self::shift_max::$t))
302312
}
313+
314+
#[inline(always)]
315+
fn overflowing_neg(self) -> ($t, bool) {
316+
((!self).wrapping_add(1), true)
317+
}
303318
}
304319
)*)
305320
}
@@ -341,6 +356,11 @@ impl OverflowingOps for usize {
341356
(r as usize, f)
342357
}
343358
#[inline(always)]
359+
fn overflowing_neg(self) -> (usize, bool) {
360+
let (r, f) = (self as u64).overflowing_neg();
361+
(r as usize, f)
362+
}
363+
#[inline(always)]
344364
fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
345365
let (r, f) = (self as u64).overflowing_shl(rhs);
346366
(r as usize, f)
@@ -386,6 +406,11 @@ impl OverflowingOps for usize {
386406
(r as usize, f)
387407
}
388408
#[inline(always)]
409+
fn overflowing_neg(self) -> (usize, bool) {
410+
let (r, f) = (self as u32).overflowing_neg();
411+
(r as usize, f)
412+
}
413+
#[inline(always)]
389414
fn overflowing_shl(self, rhs: u32) -> (usize, bool) {
390415
let (r, f) = (self as u32).overflowing_shl(rhs);
391416
(r as usize, f)
@@ -431,6 +456,11 @@ impl OverflowingOps for isize {
431456
(r as isize, f)
432457
}
433458
#[inline(always)]
459+
fn overflowing_neg(self) -> (isize, bool) {
460+
let (r, f) = (self as i64).overflowing_neg();
461+
(r as isize, f)
462+
}
463+
#[inline(always)]
434464
fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
435465
let (r, f) = (self as i64).overflowing_shl(rhs);
436466
(r as isize, f)
@@ -476,6 +506,11 @@ impl OverflowingOps for isize {
476506
(r as isize, f)
477507
}
478508
#[inline(always)]
509+
fn overflowing_neg(self) -> (isize, bool) {
510+
let (r, f) = (self as i32).overflowing_neg();
511+
(r as isize, f)
512+
}
513+
#[inline(always)]
479514
fn overflowing_shl(self, rhs: u32) -> (isize, bool) {
480515
let (r, f) = (self as i32).overflowing_shl(rhs);
481516
(r as isize, f)

0 commit comments

Comments
 (0)