core: add core::ascii::Char::from_digit#118963
core: add core::ascii::Char::from_digit#118963mina86 wants to merge 2 commits intorust-lang:masterfrom
Conversation
|
r? @cuviper (rustbot has picked a reviewer for you, use r? to override) |
|
cc @scottmcm |
This comment has been minimized.
This comment has been minimized.
Since core::ascii::Char::digit returns Some for decimal digits only, introduce core::ascii::Char::from_digit method which handles values up to 35. It mimics char::from_digit though it forgoes the radix parameter. Issue: rust-lang/libs-team#179 Issue: rust-lang#110998
| /// [`from_digit`](Self::from_digit) instead. | ||
| #[unstable(feature = "ascii_char", issue = "110998")] | ||
| #[inline] | ||
| pub const fn digit(d: u8) -> Option<Self> { |
There was a problem hiding this comment.
FWIW, that only reason I added this method was to use it for things like '0' + d in
rust/library/core/src/fmt/num.rs
Lines 149 to 150 in 604f185
But then it looks like it's not actually used. So it's possible that maybe it shouldn't have existed at all; I don't know.
(The idea was to give something to point to when people say "but '0' + d was so nice". But for hex there was never that shorthand, so having people use "…".as_ascii().unwrap()[d] might be fine for those non-decimal uses.)
There was a problem hiding this comment.
The problem at the moment is unwrap not being const, so one has to
write some annoying code:
const DIGITS: &[AsciiChar; 16] = match "...".as_ascii() {
Some(digits) => digits,
None => panic!()
};It’s not the end of the world of course, but it’s certainly less
convenient that a AsciiChar::from_digit call.
Though I can see reasons to wait for const unwrap or a"..." syntax
(proposed in the tracking issue) before considering adding this
function.
By the way, maybe for b'0' + d the solution is to implement Add?
In debug builds it would panic on overflow while on release it would
wrap (i.e. mask out most significant bit).
| #[inline] | ||
| pub const fn from_digit(d: u32) -> Option<Self> { | ||
| const DIGITS: [AsciiChar; 36] = | ||
| *b"0123456789abcdefghijklmnopqrstuvwxyz".as_ascii().unwrap(); |
There was a problem hiding this comment.
One thing I don't know how to solve here is that people might also want upper-case. Or base-64 style where a is zero. Why is lower-case special?
Oh, I guess char::from_digit does it this way. Fair enough, then, I guess.
| /// ``` | ||
| #[unstable(feature = "ascii_char", issue = "110998")] | ||
| #[inline] | ||
| pub const fn from_digit(d: u32) -> Option<Self> { |
There was a problem hiding this comment.
Is u32 the best option here? char takes u32, but char is a 4-byte type. Should this take u8 since it's a 1-byte type? Should digit also take u32, if u32 is somehow better?
There was a problem hiding this comment.
Yes, this was motivated by char::from_digit. I really don’t know what makes more sense here.
| pub const fn from_digit(d: u32) -> Option<Self> { | ||
| const DIGITS: [AsciiChar; 36] = | ||
| *b"0123456789abcdefghijklmnopqrstuvwxyz".as_ascii().unwrap(); | ||
| if d < 36 { Some(DIGITS[d as usize]) } else { None } |
There was a problem hiding this comment.
Is this more efficient than simply DIGITS.get(d as usize)? Because to me it seems like there is a nother implicit range check in DIGITS[] that could be avoided.
There was a problem hiding this comment.
get isn’t const so it cannot be used here. The compiler should be smart enough to remove the second range check.
Why do you have this difference? Anyway, between that and the choice of |
|
I have the same question as Josh. How about using the same signature as char::from_digit? |
|
☔ The latest upstream changes (presumably #120157) made this pull request unmergeable. Please resolve the merge conflicts. |
|
There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged. You can start a rebase with the following commands: The following commits are merge commits: |
|
It’s mostly because I think char::from_digit interface is over-engineered. To be honest I’m now of the opinion that as commented above it’s going to be better to implement Add. |
|
Sounds good, I'll close this in favor of a different PR to pursue an Add approach. |
Since core::ascii::Char::digit returns Some for decimal digits only,
introduce core::ascii::Char::from_digit method which handles values up
to 35. It mimics char::from_digit though it forgoes the radix
parameter.
Issue: rust-lang/libs-team#179
Issue: #110998