Skip to content

Commit 9c3d81e

Browse files
committed
Further simplification of to_digit
1 parent b3ac526 commit 9c3d81e

File tree

3 files changed

+21
-16
lines changed

3 files changed

+21
-16
lines changed

library/core/src/char/methods.rs

+9-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! impl char {}
22
3-
use crate::intrinsics::likely;
43
use crate::slice;
54
use crate::str::from_utf8_unchecked_mut;
65
use crate::unicode::printable::is_printable;
@@ -332,21 +331,16 @@ impl char {
332331
#[inline]
333332
pub fn to_digit(self, radix: u32) -> Option<u32> {
334333
assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
335-
// the code is split up here to improve execution speed for cases where
336-
// the `radix` is constant and 10 or smaller
337-
let val = if likely(radix <= 10) {
338-
// If not a digit, a number greater than radix will be created.
339-
(self as u32).wrapping_sub('0' as u32)
340-
} else {
341-
match self {
342-
'0'..='9' => self as u32 - '0' as u32,
343-
'a'..='z' => self as u32 - 'a' as u32 + 10,
344-
'A'..='Z' => self as u32 - 'A' as u32 + 10,
345-
_ => return None,
334+
// If not a digit, a number greater than radix will be created.
335+
let mut digit = (self as u32).wrapping_sub('0' as u32);
336+
if radix > 10 {
337+
if digit < 10 {
338+
return Some(digit);
346339
}
347-
};
348-
349-
if val < radix { Some(val) } else { None }
340+
// Force the 6th bit to be set to ensure ascii is lower case.
341+
digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
342+
}
343+
(digit < radix).then_some(digit)
350344
}
351345

352346
/// Returns an iterator that yields the hexadecimal Unicode escape of a

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#![feature(allow_internal_unstable)]
6767
#![feature(arbitrary_self_types)]
6868
#![feature(asm)]
69+
#![feature(bool_to_option)]
6970
#![feature(cfg_target_has_atomic)]
7071
#![feature(const_heap)]
7172
#![feature(const_alloc_layout)]

library/core/tests/char.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,20 @@ fn test_to_digit() {
6767
assert_eq!('A'.to_digit(16), Some(10));
6868
assert_eq!('b'.to_digit(16), Some(11));
6969
assert_eq!('B'.to_digit(16), Some(11));
70+
assert_eq!('A'.to_digit(36), Some(10));
7071
assert_eq!('z'.to_digit(36), Some(35));
7172
assert_eq!('Z'.to_digit(36), Some(35));
72-
assert_eq!(' '.to_digit(10), None);
73+
assert_eq!('['.to_digit(36), None);
74+
assert_eq!('`'.to_digit(36), None);
75+
assert_eq!('{'.to_digit(36), None);
7376
assert_eq!('$'.to_digit(36), None);
77+
assert_eq!('@'.to_digit(16), None);
78+
assert_eq!('G'.to_digit(16), None);
79+
assert_eq!('g'.to_digit(16), None);
80+
assert_eq!(' '.to_digit(10), None);
81+
assert_eq!('/'.to_digit(10), None);
82+
assert_eq!(':'.to_digit(10), None);
83+
assert_eq!(':'.to_digit(11), None);
7484
}
7585

7686
#[test]

0 commit comments

Comments
 (0)