Skip to content

Commit fe11483

Browse files
committed
Add functions to add unsigned and signed integers
1 parent ed93759 commit fe11483

File tree

5 files changed

+112
-15
lines changed

5 files changed

+112
-15
lines changed

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@
159159
#![feature(trait_alias)]
160160
#![feature(transparent_unions)]
161161
#![feature(try_blocks)]
162+
#![feature(uint_add_signed)]
162163
#![feature(unboxed_closures)]
163164
#![feature(unsized_fn_params)]
164165
//

library/core/src/num/mod.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ const ASCII_CASE_MASK: u8 = 0b0010_0000;
245245
#[lang = "u8"]
246246
impl u8 {
247247
widening_impl! { u8, u16, 8 }
248-
uint_impl! { u8, u8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
248+
uint_impl! { u8, u8, i8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
249249
"[0x12]", "", "" }
250250

251251
/// Checks if the value is within the ASCII range.
@@ -779,21 +779,21 @@ impl u8 {
779779
#[lang = "u16"]
780780
impl u16 {
781781
widening_impl! { u16, u32, 16 }
782-
uint_impl! { u16, u16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
782+
uint_impl! { u16, u16, i16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
783783
"[0x34, 0x12]", "[0x12, 0x34]", "", "" }
784784
}
785785

786786
#[lang = "u32"]
787787
impl u32 {
788788
widening_impl! { u32, u64, 32 }
789-
uint_impl! { u32, u32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
789+
uint_impl! { u32, u32, i32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
790790
"0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "" }
791791
}
792792

793793
#[lang = "u64"]
794794
impl u64 {
795795
widening_impl! { u64, u128, 64 }
796-
uint_impl! { u64, u64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
796+
uint_impl! { u64, u64, i64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
797797
"0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
798798
"[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
799799
"[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
@@ -802,7 +802,7 @@ impl u64 {
802802

803803
#[lang = "u128"]
804804
impl u128 {
805-
uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, 16,
805+
uint_impl! { u128, u128, i128, 128, 340282366920938463463374607431768211455, 16,
806806
"0x13f40000000000000000000000004f76", "0x4f7613f4", "0x12345678901234567890123456789012",
807807
"0x12907856341290785634129078563412", "0x48091e6a2c48091e6a2c48091e6a2c48",
808808
"[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
@@ -816,15 +816,15 @@ impl u128 {
816816
#[lang = "usize"]
817817
impl usize {
818818
widening_impl! { usize, u32, 16 }
819-
uint_impl! { usize, u16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
819+
uint_impl! { usize, u16, isize, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
820820
"[0x34, 0x12]", "[0x12, 0x34]",
821821
usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
822822
}
823823
#[cfg(target_pointer_width = "32")]
824824
#[lang = "usize"]
825825
impl usize {
826826
widening_impl! { usize, u64, 32 }
827-
uint_impl! { usize, u32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
827+
uint_impl! { usize, u32, isize, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
828828
"0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]",
829829
usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
830830
}
@@ -833,7 +833,7 @@ impl usize {
833833
#[lang = "usize"]
834834
impl usize {
835835
widening_impl! { usize, u128, 64 }
836-
uint_impl! { usize, u64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
836+
uint_impl! { usize, u64, isize, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
837837
"0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
838838
"[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
839839
"[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",

library/core/src/num/uint_macros.rs

+101-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
macro_rules! uint_impl {
2-
($SelfT:ty, $ActualT:ident, $BITS:expr, $MaxV:expr,
2+
($SelfT:ty, $ActualT:ident, $SignedT:ident, $BITS:expr, $MaxV:expr,
33
$rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
44
$reversed:expr, $le_bytes:expr, $be_bytes:expr,
55
$to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
@@ -442,6 +442,29 @@ macro_rules! uint_impl {
442442
unsafe { intrinsics::unchecked_add(self, rhs) }
443443
}
444444

445+
/// Checked addition with a signed integer. Computes `self + rhs`,
446+
/// returning `None` if overflow occurred.
447+
///
448+
/// # Examples
449+
///
450+
/// Basic usage:
451+
///
452+
/// ```
453+
/// # #![feature(uint_add_signed)]
454+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_add_signed(2), Some(3));")]
455+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".checked_add_signed(-2), None);")]
456+
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).checked_add(3), None);")]
457+
/// ```
458+
#[unstable(feature = "uint_add_signed", issue = "none")]
459+
#[rustc_const_unstable(feature = "uint_add_signed", issue = "none")]
460+
#[must_use = "this returns the result of the operation, \
461+
without modifying the original"]
462+
#[inline]
463+
pub const fn checked_add_signed(self, rhs: $SignedT) -> Option<Self> {
464+
let (a, b) = self.overflowing_add_signed(rhs);
465+
if unlikely!(b) {None} else {Some(a)}
466+
}
467+
445468
/// Checked integer subtraction. Computes `self - rhs`, returning
446469
/// `None` if overflow occurred.
447470
///
@@ -995,6 +1018,32 @@ macro_rules! uint_impl {
9951018
intrinsics::saturating_add(self, rhs)
9961019
}
9971020

1021+
/// Saturating addition with a signed integer. Computes `self + rhs`,
1022+
/// saturating at the numeric bounds instead of overflowing.
1023+
///
1024+
/// # Examples
1025+
///
1026+
/// Basic usage:
1027+
///
1028+
/// ```
1029+
/// # #![feature(uint_add_signed)]
1030+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_add_signed(2), 3);")]
1031+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".saturating_add_signed(-2), 0);")]
1032+
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).saturating_add_signed(4), ", stringify!($SelfT), "::MAX);")]
1033+
/// ```
1034+
#[unstable(feature = "uint_add_signed", issue = "none")]
1035+
#[rustc_const_unstable(feature = "uint_add_signed", issue = "none")]
1036+
#[must_use = "this returns the result of the operation, \
1037+
without modifying the original"]
1038+
#[inline]
1039+
pub const fn saturating_add_signed(self, rhs: $SignedT) -> Self {
1040+
if rhs >= 0 {
1041+
self.saturating_add(rhs as Self)
1042+
} else {
1043+
self.saturating_sub(rhs.unsigned_abs())
1044+
}
1045+
}
1046+
9981047
/// Saturating integer subtraction. Computes `self - rhs`, saturating
9991048
/// at the numeric bounds instead of overflowing.
10001049
///
@@ -1111,6 +1160,28 @@ macro_rules! uint_impl {
11111160
intrinsics::wrapping_add(self, rhs)
11121161
}
11131162

1163+
/// Wrapping (modular) addition with a signed integer. Computes
1164+
/// `self + rhs`, wrapping around at the boundary of the type.
1165+
///
1166+
/// # Examples
1167+
///
1168+
/// Basic usage:
1169+
///
1170+
/// ```
1171+
/// # #![feature(uint_add_signed)]
1172+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_add_signed(2), 3);")]
1173+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".wrapping_add_signed(-2), ", stringify!($SelfT), "::MAX);")]
1174+
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).wrapping_add_signed(4), 1);")]
1175+
/// ```
1176+
#[unstable(feature = "uint_add_signed", issue = "none")]
1177+
#[rustc_const_unstable(feature = "uint_add_signed", issue = "none")]
1178+
#[must_use = "this returns the result of the operation, \
1179+
without modifying the original"]
1180+
#[inline]
1181+
pub const fn wrapping_add_signed(self, rhs: $SignedT) -> Self {
1182+
self.wrapping_add(rhs as Self)
1183+
}
1184+
11141185
/// Wrapping (modular) subtraction. Computes `self - rhs`,
11151186
/// wrapping around at the boundary of the type.
11161187
///
@@ -1435,6 +1506,35 @@ macro_rules! uint_impl {
14351506
(c, b | d)
14361507
}
14371508

1509+
/// Calculates `self` + `rhs` with a signed `rhs`
1510+
///
1511+
/// Returns a tuple of the addition along with a boolean indicating
1512+
/// whether an arithmetic overflow would occur. If an overflow would
1513+
/// have occurred then the wrapped value is returned.
1514+
///
1515+
/// # Examples
1516+
///
1517+
/// Basic usage:
1518+
///
1519+
/// ```
1520+
/// # #![feature(uint_add_signed)]
1521+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_add_signed(2), (3, false));")]
1522+
#[doc = concat!("assert_eq!(1", stringify!($SelfT), ".overflowing_add_signed(-2), (", stringify!($SelfT), "::MAX, true));")]
1523+
#[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).overflowing_add_signed(4), (1, true));")]
1524+
/// ```
1525+
#[unstable(feature = "uint_add_signed", issue = "none")]
1526+
#[rustc_const_unstable(feature = "uint_add_signed", issue = "none")]
1527+
#[must_use = "this returns the result of the operation, \
1528+
without modifying the original"]
1529+
#[inline]
1530+
pub const fn overflowing_add_signed(self, rhs: $SignedT) -> (Self, bool) {
1531+
if rhs >= 0 {
1532+
self.overflowing_add(rhs as Self)
1533+
} else {
1534+
self.overflowing_sub(rhs.unsigned_abs())
1535+
}
1536+
}
1537+
14381538
/// Calculates `self` - `rhs`
14391539
///
14401540
/// Returns a tuple of the subtraction along with a boolean indicating

library/std/src/io/cursor.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,7 @@ where
292292
SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n),
293293
SeekFrom::Current(n) => (self.pos, n),
294294
};
295-
let new_pos = if offset >= 0 {
296-
base_pos.checked_add(offset as u64)
297-
} else {
298-
base_pos.checked_sub((offset.wrapping_neg()) as u64)
299-
};
300-
match new_pos {
295+
match base_pos.checked_add_signed(offset) {
301296
Some(n) => {
302297
self.pos = n;
303298
Ok(self.pos)

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@
333333
#![feature(try_blocks)]
334334
#![feature(try_reserve)]
335335
#![feature(try_reserve_kind)]
336+
#![feature(uint_add_signed)]
336337
#![feature(unboxed_closures)]
337338
#![feature(unwrap_infallible)]
338339
#![feature(vec_into_raw_parts)]

0 commit comments

Comments
 (0)