Skip to content

Commit 4bfea71

Browse files
committed
incorporating feedback
1 parent d27454e commit 4bfea71

File tree

1 file changed

+42
-34
lines changed

1 file changed

+42
-34
lines changed

library/core/src/num/mod.rs

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -975,9 +975,9 @@ trait FromStrRadixHelper: PartialOrd + Copy {
975975
fn checked_mul(&self, other: u32) -> Option<Self>;
976976
fn checked_sub(&self, other: u32) -> Option<Self>;
977977
fn checked_add(&self, other: u32) -> Option<Self>;
978-
unsafe fn unchecked_mul(&self, other: u32) -> Self;
979-
unsafe fn unchecked_sub(&self, other: u32) -> Self;
980-
unsafe fn unchecked_add(&self, other: u32) -> Self;
978+
unsafe fn unchecked_mul(self, other: u32) -> Self;
979+
unsafe fn unchecked_sub(self, other: u32) -> Self;
980+
unsafe fn unchecked_add(self, other: u32) -> Self;
981981
}
982982

983983
macro_rules! from_str_radix_int_impl {
@@ -993,7 +993,7 @@ macro_rules! from_str_radix_int_impl {
993993
}
994994
from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
995995

996-
macro_rules! doit {
996+
macro_rules! impl_helper_for {
997997
($($t:ty)*) => ($(impl FromStrRadixHelper for $t {
998998
const MIN: Self = Self::MIN;
999999
#[inline]
@@ -1011,29 +1011,29 @@ macro_rules! doit {
10111011
Self::checked_add(*self, other as Self)
10121012
}
10131013
#[inline]
1014-
unsafe fn unchecked_mul(&self, other: u32) -> Self {
1014+
unsafe fn unchecked_mul(self, other: u32) -> Self {
10151015
// SAFETY: Conditions of `Self::unchecked_mul` must be upheld by the caller.
10161016
unsafe {
1017-
Self::unchecked_mul(*self, other as Self)
1017+
Self::unchecked_mul(self, other as Self)
10181018
}
10191019
}
10201020
#[inline]
1021-
unsafe fn unchecked_sub(&self, other: u32) -> Self {
1021+
unsafe fn unchecked_sub(self, other: u32) -> Self {
10221022
// SAFETY: Conditions of `Self::unchecked_sub` must be upheld by the caller.
10231023
unsafe {
1024-
Self::unchecked_sub(*self, other as Self)
1024+
Self::unchecked_sub(self, other as Self)
10251025
}
10261026
}
10271027
#[inline]
1028-
unsafe fn unchecked_add(&self, other: u32) -> Self {
1028+
unsafe fn unchecked_add(self, other: u32) -> Self {
10291029
// SAFETY: Conditions of `Self::unchecked_add` must be upheld by the caller.
10301030
unsafe {
1031-
Self::unchecked_add(*self, other as Self)
1031+
Self::unchecked_add(self, other as Self)
10321032
}
10331033
}
10341034
})*)
10351035
}
1036-
doit! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
1036+
impl_helper_for! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
10371037

10381038
fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, ParseIntError> {
10391039
use self::IntErrorKind::*;
@@ -1078,41 +1078,49 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, Par
10781078
// `u8::MAX` is `ff` - any str of len 2 is guaranteed to not overflow.
10791079
// `i8::MAX` is `7f` - only a str of len 1 is guaranteed to not overflow.
10801080
unsafe {
1081-
macro_rules! run_loop {
1081+
macro_rules! run_unchecked_loop {
10821082
($unchecked_additive_op:ident) => {
10831083
for &c in digits {
10841084
result = result.unchecked_mul(radix);
10851085
let x = (c as char).to_digit(radix).ok_or(PIE { kind: InvalidDigit })?;
1086-
result = T::$unchecked_additive_op(&result, x);
1086+
result = T::$unchecked_additive_op(result, x);
10871087
}
10881088
};
10891089
}
10901090
if is_positive {
1091-
run_loop!(unchecked_add)
1091+
run_unchecked_loop!(unchecked_add)
10921092
} else {
1093-
run_loop!(unchecked_sub)
1093+
run_unchecked_loop!(unchecked_sub)
10941094
};
10951095
}
1096-
} else {
1097-
let additive_op = if is_positive { T::checked_add } else { T::checked_sub };
1098-
let overflow_err = || PIE { kind: if is_positive { PosOverflow } else { NegOverflow } };
1099-
1100-
for &c in digits {
1101-
// When `radix` is passed in as a literal, rather than doing a slow `imul`
1102-
// the compiler can use shifts if `radix` can be expressed as a
1103-
// sum of powers of 2 (x*10 can be written as x*8 + x*2).
1104-
// When the compiler can't use these optimisations,
1105-
// the latency of the multiplication can be hidden by issuing it
1106-
// before the result is needed to improve performance on
1107-
// modern out-of-order CPU as multiplication here is slower
1108-
// than the other instructions, we can get the end result faster
1109-
// doing multiplication first and let the CPU spends other cycles
1110-
// doing other computation and get multiplication result later.
1111-
let mul = result.checked_mul(radix);
1112-
let x = (c as char).to_digit(radix).ok_or(PIE { kind: InvalidDigit })?;
1113-
result = mul.ok_or_else(overflow_err)?;
1114-
result = additive_op(&result, x).ok_or_else(overflow_err)?;
1096+
} else {
1097+
macro_rules! run_checked_loop {
1098+
($checked_additive_op:ident, $overflow_err:ident) => {
1099+
for &c in digits {
1100+
// When `radix` is passed in as a literal, rather than doing a slow `imul`
1101+
// the compiler can use shifts if `radix` can be expressed as a
1102+
// sum of powers of 2 (x*10 can be written as x*8 + x*2).
1103+
// When the compiler can't use these optimisations,
1104+
// the latency of the multiplication can be hidden by issuing it
1105+
// before the result is needed to improve performance on
1106+
// modern out-of-order CPU as multiplication here is slower
1107+
// than the other instructions, we can get the end result faster
1108+
// doing multiplication first and let the CPU spends other cycles
1109+
// doing other computation and get multiplication result later.
1110+
let mul = result.checked_mul(radix);
1111+
let x = (c as char).to_digit(radix).ok_or(PIE { kind: InvalidDigit })?;
1112+
result = mul.ok_or_else($overflow_err)?;
1113+
result = T::$checked_additive_op(&result, x).ok_or_else($overflow_err)?;
1114+
}
1115+
}
11151116
}
1117+
if is_positive {
1118+
let overflow_err = || PIE { kind: PosOverflow };
1119+
run_checked_loop!(checked_add, overflow_err)
1120+
} else {
1121+
let overflow_err = || PIE { kind: NegOverflow };
1122+
run_checked_loop!(checked_sub, overflow_err)
1123+
};
11161124
}
11171125
Ok(result)
11181126
}

0 commit comments

Comments
 (0)