Skip to content

Commit 9faf621

Browse files
committed
Add methods to add/sub uX to/from iX
1 parent b5dd522 commit 9faf621

File tree

4 files changed

+204
-14
lines changed

4 files changed

+204
-14
lines changed

library/core/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
#![feature(link_llvm_intrinsics)]
143143
#![feature(llvm_asm)]
144144
#![feature(min_specialization)]
145+
#![feature(mixed_integer_ops)]
145146
#![cfg_attr(not(bootstrap), feature(must_not_suspend))]
146147
#![feature(negative_impls)]
147148
#![feature(never_type)]
@@ -159,7 +160,6 @@
159160
#![feature(trait_alias)]
160161
#![feature(transparent_unions)]
161162
#![feature(try_blocks)]
162-
#![feature(uint_add_signed)]
163163
#![feature(unboxed_closures)]
164164
#![feature(unsized_fn_params)]
165165
//

library/core/src/num/int_macros.rs

+190
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,28 @@ macro_rules! int_impl {
433433
unsafe { intrinsics::unchecked_add(self, rhs) }
434434
}
435435

436+
/// Checked addition with an unsigned integer. Computes `self + rhs`,
437+
/// returning `None` if overflow occurred.
438+
///
439+
/// # Examples
440+
///
441+
/// Basic usage:
442+
///
443+
/// ```
444+
/// # #![feature(mixed_integer_ops)]
445+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_add_unsigned(2), Some(3));")]
446+
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add_unsigned(3), None);")]
447+
/// ```
448+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
449+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
450+
#[must_use = "this returns the result of the operation, \
451+
without modifying the original"]
452+
#[inline]
453+
pub const fn checked_add_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
454+
let (a, b) = self.overflowing_add_unsigned(rhs);
455+
if unlikely!(b) {None} else {Some(a)}
456+
}
457+
436458
/// Checked integer subtraction. Computes `self - rhs`, returning `None` if
437459
/// overflow occurred.
438460
///
@@ -479,6 +501,28 @@ macro_rules! int_impl {
479501
unsafe { intrinsics::unchecked_sub(self, rhs) }
480502
}
481503

504+
/// Checked addition with an unsigned integer. Computes `self + rhs`,
505+
/// returning `None` if overflow occurred.
506+
///
507+
/// # Examples
508+
///
509+
/// Basic usage:
510+
///
511+
/// ```
512+
/// # #![feature(mixed_integer_ops)]
513+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_sub_unsigned(2), Some(-1));")]
514+
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 2).checked_sub_unsigned(3), None);")]
515+
/// ```
516+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
517+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
518+
#[must_use = "this returns the result of the operation, \
519+
without modifying the original"]
520+
#[inline]
521+
pub const fn checked_sub_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
522+
let (a, b) = self.overflowing_sub_unsigned(rhs);
523+
if unlikely!(b) {None} else {Some(a)}
524+
}
525+
482526
/// Checked integer multiplication. Computes `self * rhs`, returning `None` if
483527
/// overflow occurred.
484528
///
@@ -822,6 +866,31 @@ macro_rules! int_impl {
822866
intrinsics::saturating_add(self, rhs)
823867
}
824868

869+
/// Saturating addition with an unsigned integer. Computes `self + rhs`,
870+
/// saturating at the numeric bounds instead of overflowing.
871+
///
872+
/// # Examples
873+
///
874+
/// Basic usage:
875+
///
876+
/// ```
877+
/// # #![feature(mixed_integer_ops)]
878+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_add_unsigned(2), 3);")]
879+
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.saturating_add_unsigned(100), ", stringify!($SelfT), "::MAX);")]
880+
/// ```
881+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
882+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
883+
#[must_use = "this returns the result of the operation, \
884+
without modifying the original"]
885+
#[inline]
886+
pub const fn saturating_add_unsigned(self, rhs: $UnsignedT) -> Self {
887+
// Overflow can only happen at the upper bound
888+
match self.checked_add_unsigned(rhs) {
889+
Some(x) => x,
890+
None => Self::MAX,
891+
}
892+
}
893+
825894
/// Saturating integer subtraction. Computes `self - rhs`, saturating at the
826895
/// numeric bounds instead of overflowing.
827896
///
@@ -843,6 +912,31 @@ macro_rules! int_impl {
843912
intrinsics::saturating_sub(self, rhs)
844913
}
845914

915+
/// Saturating substraction with an unsigned integer. Computes `self - rhs`,
916+
/// saturating at the numeric bounds instead of overflowing.
917+
///
918+
/// # Examples
919+
///
920+
/// Basic usage:
921+
///
922+
/// ```
923+
/// # #![feature(mixed_integer_ops)]
924+
#[doc = concat!("assert_eq!(100", stringify!($SelfT), ".saturating_sub_unsigned(127), -27);")]
925+
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.saturating_sub_unsigned(100), ", stringify!($SelfT), "::MIN);")]
926+
/// ```
927+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
928+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
929+
#[must_use = "this returns the result of the operation, \
930+
without modifying the original"]
931+
#[inline]
932+
pub const fn saturating_sub_unsigned(self, rhs: $UnsignedT) -> Self {
933+
// Overflow can only happen at the lower bound
934+
match self.checked_sub_unsigned(rhs) {
935+
Some(x) => x,
936+
None => Self::MIN,
937+
}
938+
}
939+
846940
/// Saturating integer negation. Computes `-self`, returning `MAX` if `self == MIN`
847941
/// instead of overflowing.
848942
///
@@ -998,6 +1092,27 @@ macro_rules! int_impl {
9981092
intrinsics::wrapping_add(self, rhs)
9991093
}
10001094

1095+
/// Wrapping (modular) addition with an unsigned integer. Computes
1096+
/// `self + rhs`, wrapping around at the boundary of the type.
1097+
///
1098+
/// # Examples
1099+
///
1100+
/// Basic usage:
1101+
///
1102+
/// ```
1103+
/// # #![feature(mixed_integer_ops)]
1104+
#[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_add_unsigned(27), 127);")]
1105+
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.wrapping_add_unsigned(2), ", stringify!($SelfT), "::MIN + 1);")]
1106+
/// ```
1107+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
1108+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
1109+
#[must_use = "this returns the result of the operation, \
1110+
without modifying the original"]
1111+
#[inline(always)]
1112+
pub const fn wrapping_add_unsigned(self, rhs: $UnsignedT) -> Self {
1113+
self.wrapping_add(rhs as Self)
1114+
}
1115+
10011116
/// Wrapping (modular) subtraction. Computes `self - rhs`, wrapping around at the
10021117
/// boundary of the type.
10031118
///
@@ -1018,6 +1133,27 @@ macro_rules! int_impl {
10181133
intrinsics::wrapping_sub(self, rhs)
10191134
}
10201135

1136+
/// Wrapping (modular) substraction with an unsigned integer. Computes
1137+
/// `self - rhs`, wrapping around at the boundary of the type.
1138+
///
1139+
/// # Examples
1140+
///
1141+
/// Basic usage:
1142+
///
1143+
/// ```
1144+
/// # #![feature(mixed_integer_ops)]
1145+
#[doc = concat!("assert_eq!(0", stringify!($SelfT), ".wrapping_sub_unsigned(127), -127);")]
1146+
#[doc = concat!("assert_eq!((-2", stringify!($SelfT), ").wrapping_sub_unsigned(", stringify!($UnsignedT), "::MAX), -1);")]
1147+
/// ```
1148+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
1149+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
1150+
#[must_use = "this returns the result of the operation, \
1151+
without modifying the original"]
1152+
#[inline(always)]
1153+
pub const fn wrapping_sub_unsigned(self, rhs: $UnsignedT) -> Self {
1154+
self.wrapping_sub(rhs as Self)
1155+
}
1156+
10211157
/// Wrapping (modular) multiplication. Computes `self * rhs`, wrapping around at
10221158
/// the boundary of the type.
10231159
///
@@ -1368,6 +1504,33 @@ macro_rules! int_impl {
13681504
(sum as $SelfT, carry)
13691505
}
13701506

1507+
/// Calculates `self` + `rhs` with an unsigned `rhs`
1508+
///
1509+
/// Returns a tuple of the addition along with a boolean indicating
1510+
/// whether an arithmetic overflow would occur. If an overflow would
1511+
/// have occurred then the wrapped value is returned.
1512+
///
1513+
/// # Examples
1514+
///
1515+
/// Basic usage:
1516+
///
1517+
/// ```
1518+
/// # #![feature(mixed_integer_ops)]
1519+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_add_unsigned(2), (3, false));")]
1520+
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN).overflowing_add_unsigned(", stringify!($UnsignedT), "::MAX), (", stringify!($SelfT), "::MAX, false));")]
1521+
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).overflowing_add_unsigned(3), (", stringify!($SelfT), "::MIN, true));")]
1522+
/// ```
1523+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
1524+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
1525+
#[must_use = "this returns the result of the operation, \
1526+
without modifying the original"]
1527+
#[inline]
1528+
pub const fn overflowing_add_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
1529+
let rhs = rhs as Self;
1530+
let (res, overflowed) = self.overflowing_add(rhs);
1531+
(res, overflowed ^ (rhs < 0))
1532+
}
1533+
13711534
/// Calculates `self` - `rhs`
13721535
///
13731536
/// Returns a tuple of the subtraction along with a boolean indicating whether an arithmetic overflow
@@ -1419,6 +1582,33 @@ macro_rules! int_impl {
14191582
(sum as $SelfT, borrow)
14201583
}
14211584

1585+
/// Calculates `self` - `rhs` with an unsigned `rhs`
1586+
///
1587+
/// Returns a tuple of the substraction along with a boolean indicating
1588+
/// whether an arithmetic overflow would occur. If an overflow would
1589+
/// have occurred then the wrapped value is returned.
1590+
///
1591+
/// # Examples
1592+
///
1593+
/// Basic usage:
1594+
///
1595+
/// ```
1596+
/// # #![feature(mixed_integer_ops)]
1597+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_sub_unsigned(2), (-1, false));")]
1598+
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX).overflowing_sub_unsigned(", stringify!($UnsignedT), "::MAX), (", stringify!($SelfT), "::MIN, false));")]
1599+
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 2).overflowing_sub_unsigned(3), (", stringify!($SelfT), "::MAX, true));")]
1600+
/// ```
1601+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
1602+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
1603+
#[must_use = "this returns the result of the operation, \
1604+
without modifying the original"]
1605+
#[inline]
1606+
pub const fn overflowing_sub_unsigned(self, rhs: $UnsignedT) -> (Self, bool) {
1607+
let rhs = rhs as Self;
1608+
let (res, overflowed) = self.overflowing_sub(rhs);
1609+
(res, overflowed ^ (rhs < 0))
1610+
}
1611+
14221612
/// Calculates the multiplication of `self` and `rhs`.
14231613
///
14241614
/// Returns a tuple of the multiplication along with a boolean indicating whether an arithmetic overflow

library/core/src/num/uint_macros.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -450,13 +450,13 @@ macro_rules! uint_impl {
450450
/// Basic usage:
451451
///
452452
/// ```
453-
/// # #![feature(uint_add_signed)]
453+
/// # #![feature(mixed_integer_ops)]
454454
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_add_signed(2), Some(3));")]
455455
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_add_signed(-2), None);")]
456456
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add_signed(3), None);")]
457457
/// ```
458-
#[unstable(feature = "uint_add_signed", issue = "none")]
459-
#[rustc_const_unstable(feature = "uint_add_signed", issue = "none")]
458+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
459+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
460460
#[must_use = "this returns the result of the operation, \
461461
without modifying the original"]
462462
#[inline]
@@ -1026,13 +1026,13 @@ macro_rules! uint_impl {
10261026
/// Basic usage:
10271027
///
10281028
/// ```
1029-
/// # #![feature(uint_add_signed)]
1029+
/// # #![feature(mixed_integer_ops)]
10301030
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_add_signed(2), 3);")]
10311031
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_add_signed(-2), 0);")]
10321032
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).saturating_add_signed(4), ", stringify!($SelfT), "::MAX);")]
10331033
/// ```
1034-
#[unstable(feature = "uint_add_signed", issue = "none")]
1035-
#[rustc_const_unstable(feature = "uint_add_signed", issue = "none")]
1034+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
1035+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
10361036
#[must_use = "this returns the result of the operation, \
10371037
without modifying the original"]
10381038
#[inline]
@@ -1168,13 +1168,13 @@ macro_rules! uint_impl {
11681168
/// Basic usage:
11691169
///
11701170
/// ```
1171-
/// # #![feature(uint_add_signed)]
1171+
/// # #![feature(mixed_integer_ops)]
11721172
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_add_signed(2), 3);")]
11731173
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_add_signed(-2), ", stringify!($SelfT), "::MAX);")]
11741174
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).wrapping_add_signed(4), 1);")]
11751175
/// ```
1176-
#[unstable(feature = "uint_add_signed", issue = "none")]
1177-
#[rustc_const_unstable(feature = "uint_add_signed", issue = "none")]
1176+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
1177+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
11781178
#[must_use = "this returns the result of the operation, \
11791179
without modifying the original"]
11801180
#[inline]
@@ -1517,13 +1517,13 @@ macro_rules! uint_impl {
15171517
/// Basic usage:
15181518
///
15191519
/// ```
1520-
/// # #![feature(uint_add_signed)]
1520+
/// # #![feature(mixed_integer_ops)]
15211521
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_add_signed(2), (3, false));")]
15221522
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_add_signed(-2), (", stringify!($SelfT), "::MAX, true));")]
15231523
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).overflowing_add_signed(4), (1, true));")]
15241524
/// ```
1525-
#[unstable(feature = "uint_add_signed", issue = "none")]
1526-
#[rustc_const_unstable(feature = "uint_add_signed", issue = "none")]
1525+
#[unstable(feature = "mixed_integer_ops", issue = "87840")]
1526+
#[rustc_const_unstable(feature = "mixed_integer_ops", issue = "87840")]
15271527
#[must_use = "this returns the result of the operation, \
15281528
without modifying the original"]
15291529
#[inline]

library/std/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@
297297
#![feature(maybe_uninit_slice)]
298298
#![feature(maybe_uninit_uninit_array)]
299299
#![feature(min_specialization)]
300+
#![feature(mixed_integer_ops)]
300301
#![cfg_attr(not(bootstrap), feature(must_not_suspend))]
301302
#![feature(needs_panic_runtime)]
302303
#![feature(negative_impls)]
@@ -333,7 +334,6 @@
333334
#![feature(try_blocks)]
334335
#![feature(try_reserve)]
335336
#![feature(try_reserve_kind)]
336-
#![feature(uint_add_signed)]
337337
#![feature(unboxed_closures)]
338338
#![feature(unwrap_infallible)]
339339
#![feature(vec_into_raw_parts)]

0 commit comments

Comments
 (0)