Auto merge of #134969 - Marcondiro:master, r=jhpratt,programmerjake
char to_digit: avoid unnecessary casts to u64 Hello, in the `char::to_digit` method there are a few `as u64` casts that are not strictly necessary. I assume that the reason behind these casts is to avoid possible overflows in the `+ 10` add. This PR removes the aforementioned casts, avoiding the overflow issue by slightly modifying the ASCII letter to int mapping. Thanks, Happy new year.
This commit is contained in:
commit
eeeff9a66c
1 changed files with 11 additions and 7 deletions
|
@ -394,17 +394,21 @@ impl char {
|
||||||
);
|
);
|
||||||
// check radix to remove letter handling code when radix is a known constant
|
// check radix to remove letter handling code when radix is a known constant
|
||||||
let value = if self > '9' && radix > 10 {
|
let value = if self > '9' && radix > 10 {
|
||||||
// convert ASCII letters to lowercase
|
// mask to convert ASCII letters to uppercase
|
||||||
let lower = self as u32 | 0x20;
|
const TO_UPPERCASE_MASK: u32 = !0b0010_0000;
|
||||||
// convert an ASCII letter to the corresponding value,
|
// Converts an ASCII letter to its corresponding integer value:
|
||||||
// non-letters convert to values > 36
|
// A-Z => 10-35, a-z => 10-35. Other characters produce values >= 36.
|
||||||
lower.wrapping_sub('a' as u32) as u64 + 10
|
//
|
||||||
|
// Add Overflow Safety:
|
||||||
|
// By applying the mask after the subtraction, the first addendum is
|
||||||
|
// constrained such that it never exceeds u32::MAX - 0x20.
|
||||||
|
((self as u32).wrapping_sub('A' as u32) & TO_UPPERCASE_MASK) + 10
|
||||||
} else {
|
} else {
|
||||||
// convert digit to value, non-digits wrap to values > 36
|
// convert digit to value, non-digits wrap to values > 36
|
||||||
(self as u32).wrapping_sub('0' as u32) as u64
|
(self as u32).wrapping_sub('0' as u32)
|
||||||
};
|
};
|
||||||
// FIXME(const-hack): once then_some is const fn, use it here
|
// FIXME(const-hack): once then_some is const fn, use it here
|
||||||
if value < radix as u64 { Some(value as u32) } else { None }
|
if value < radix { Some(value) } else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator that yields the hexadecimal Unicode escape of a
|
/// Returns an iterator that yields the hexadecimal Unicode escape of a
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue