diff options
| author | kennytm <kennytm@gmail.com> | 2017-11-29 18:37:44 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-11-29 18:37:44 +0800 |
| commit | 963ab91dd40a57c061229f006dcf8ce271d89664 (patch) | |
| tree | 40c0aaa5494f132492f7fb1fdc94cec54723f612 /src/libstd | |
| parent | 0ec3aee569a8a34117d265e48eb980a955a2186d (diff) | |
| parent | c5aad96739228e8e05b597b32ee7126c843b7228 (diff) | |
| download | rust-963ab91dd40a57c061229f006dcf8ce271d89664.tar.gz rust-963ab91dd40a57c061229f006dcf8ce271d89664.zip | |
Rollup merge of #46077 - LukasKalbertodt:stabilize-ascii-ctype, r=alexcrichton
Stabilize some `ascii_ctype` methods As discussed in #39658, this PR stabilizes those methods for `u8` and `char`. All inherent `ascii_ctype` for `[u8]` and `str` are removed as we prefer the more explicit version `s.chars().all(|c| c.is_ascii_())`. This PR doesn't modify the `AsciiExt` trait. There, the `ascii_ctype` methods are still unstable. It is planned to remove those in the future (I think). I had to modify some code in `ascii.rs` to properly implement `AsciiExt` for all types. Fixes #39658.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/ascii.rs | 209 |
1 files changed, 166 insertions, 43 deletions
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 96d719c528c..312da203574 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -490,77 +490,199 @@ impl AsciiExt for [u8] { } } -macro_rules! impl_by_delegating { - ($ty:ty, $owned:ty) => { - #[stable(feature = "rust1", since = "1.0.0")] - impl AsciiExt for $ty { - type Owned = $owned; +macro_rules! delegating_ascii_methods { + () => { + #[inline] + fn is_ascii(&self) -> bool { self.is_ascii() } - #[inline] - fn is_ascii(&self) -> bool { self.is_ascii() } + #[inline] + fn to_ascii_uppercase(&self) -> Self::Owned { self.to_ascii_uppercase() } - #[inline] - fn to_ascii_uppercase(&self) -> Self::Owned { self.to_ascii_uppercase() } + #[inline] + fn to_ascii_lowercase(&self) -> Self::Owned { self.to_ascii_lowercase() } - #[inline] - fn to_ascii_lowercase(&self) -> Self::Owned { self.to_ascii_lowercase() } + #[inline] + fn eq_ignore_ascii_case(&self, o: &Self) -> bool { self.eq_ignore_ascii_case(o) } - #[inline] - fn eq_ignore_ascii_case(&self, o: &Self) -> bool { self.eq_ignore_ascii_case(o) } + #[inline] + fn make_ascii_uppercase(&mut self) { self.make_ascii_uppercase(); } - #[inline] - fn make_ascii_uppercase(&mut self) { self.make_ascii_uppercase(); } - - #[inline] - fn make_ascii_lowercase(&mut self) { self.make_ascii_lowercase(); } + #[inline] + fn make_ascii_lowercase(&mut self) { self.make_ascii_lowercase(); } + } +} - #[inline] - fn is_ascii_alphabetic(&self) -> bool { self.is_ascii_alphabetic() } +macro_rules! delegating_ascii_ctype_methods { + () => { + #[inline] + fn is_ascii_alphabetic(&self) -> bool { self.is_ascii_alphabetic() } - #[inline] - fn is_ascii_uppercase(&self) -> bool { self.is_ascii_uppercase() } + #[inline] + fn is_ascii_uppercase(&self) -> bool { self.is_ascii_uppercase() } - #[inline] - fn is_ascii_lowercase(&self) -> bool { self.is_ascii_lowercase() } + #[inline] + fn is_ascii_lowercase(&self) -> bool { self.is_ascii_lowercase() } - #[inline] - fn is_ascii_alphanumeric(&self) -> bool { self.is_ascii_alphanumeric() } + #[inline] + fn is_ascii_alphanumeric(&self) -> bool { self.is_ascii_alphanumeric() } - #[inline] - fn is_ascii_digit(&self) -> bool { self.is_ascii_digit() } + #[inline] + fn is_ascii_digit(&self) -> bool { self.is_ascii_digit() } - #[inline] - fn is_ascii_hexdigit(&self) -> bool { self.is_ascii_hexdigit() } + #[inline] + fn is_ascii_hexdigit(&self) -> bool { self.is_ascii_hexdigit() } - #[inline] - fn is_ascii_punctuation(&self) -> bool { self.is_ascii_punctuation() } + #[inline] + fn is_ascii_punctuation(&self) -> bool { self.is_ascii_punctuation() } - #[inline] - fn is_ascii_graphic(&self) -> bool { self.is_ascii_graphic() } + #[inline] + fn is_ascii_graphic(&self) -> bool { self.is_ascii_graphic() } - #[inline] - fn is_ascii_whitespace(&self) -> bool { self.is_ascii_whitespace() } + #[inline] + fn is_ascii_whitespace(&self) -> bool { self.is_ascii_whitespace() } - #[inline] - fn is_ascii_control(&self) -> bool { self.is_ascii_control() } - } + #[inline] + fn is_ascii_control(&self) -> bool { self.is_ascii_control() } } } -impl_by_delegating!(u8, u8); -impl_by_delegating!(char, char); +#[stable(feature = "rust1", since = "1.0.0")] +impl AsciiExt for u8 { + type Owned = u8; + + delegating_ascii_methods!(); + delegating_ascii_ctype_methods!(); +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl AsciiExt for char { + type Owned = char; + + delegating_ascii_methods!(); + delegating_ascii_ctype_methods!(); +} // FIXME(LukasKalbertodt): the macro invocation should replace the impl block // for `[u8]` above. But this is not possible until the stage0 compiler is new // enough to contain the inherent ascii methods for `[u8]`. #[cfg(not(stage0))] -impl_by_delegating!([u8], Vec<u8>); +#[stable(feature = "rust1", since = "1.0.0")] +impl AsciiExt for [u8] { + type Owned = Vec<u8>; + + delegating_ascii_methods!(); + + #[inline] + fn is_ascii_alphabetic(&self) -> bool { + self.iter().all(|b| b.is_ascii_alphabetic()) + } + + #[inline] + fn is_ascii_uppercase(&self) -> bool { + self.iter().all(|b| b.is_ascii_uppercase()) + } + + #[inline] + fn is_ascii_lowercase(&self) -> bool { + self.iter().all(|b| b.is_ascii_lowercase()) + } + + #[inline] + fn is_ascii_alphanumeric(&self) -> bool { + self.iter().all(|b| b.is_ascii_alphanumeric()) + } + + #[inline] + fn is_ascii_digit(&self) -> bool { + self.iter().all(|b| b.is_ascii_digit()) + } + + #[inline] + fn is_ascii_hexdigit(&self) -> bool { + self.iter().all(|b| b.is_ascii_hexdigit()) + } + + #[inline] + fn is_ascii_punctuation(&self) -> bool { + self.iter().all(|b| b.is_ascii_punctuation()) + } + + #[inline] + fn is_ascii_graphic(&self) -> bool { + self.iter().all(|b| b.is_ascii_graphic()) + } + + #[inline] + fn is_ascii_whitespace(&self) -> bool { + self.iter().all(|b| b.is_ascii_whitespace()) + } + + #[inline] + fn is_ascii_control(&self) -> bool { + self.iter().all(|b| b.is_ascii_control()) + } +} // FIXME(LukasKalbertodt): the macro invocation should replace the impl block // for `str` above. But this is not possible until the stage0 compiler is new // enough to contain the inherent ascii methods for `str`. #[cfg(not(stage0))] -impl_by_delegating!(str, String); +#[stable(feature = "rust1", since = "1.0.0")] +impl AsciiExt for str { + type Owned = String; + + delegating_ascii_methods!(); + + #[inline] + fn is_ascii_alphabetic(&self) -> bool { + self.bytes().all(|b| b.is_ascii_alphabetic()) + } + + #[inline] + fn is_ascii_uppercase(&self) -> bool { + self.bytes().all(|b| b.is_ascii_uppercase()) + } + + #[inline] + fn is_ascii_lowercase(&self) -> bool { + self.bytes().all(|b| b.is_ascii_lowercase()) + } + + #[inline] + fn is_ascii_alphanumeric(&self) -> bool { + self.bytes().all(|b| b.is_ascii_alphanumeric()) + } + + #[inline] + fn is_ascii_digit(&self) -> bool { + self.bytes().all(|b| b.is_ascii_digit()) + } + + #[inline] + fn is_ascii_hexdigit(&self) -> bool { + self.bytes().all(|b| b.is_ascii_hexdigit()) + } + + #[inline] + fn is_ascii_punctuation(&self) -> bool { + self.bytes().all(|b| b.is_ascii_punctuation()) + } + + #[inline] + fn is_ascii_graphic(&self) -> bool { + self.bytes().all(|b| b.is_ascii_graphic()) + } + + #[inline] + fn is_ascii_whitespace(&self) -> bool { + self.bytes().all(|b| b.is_ascii_whitespace()) + } + + #[inline] + fn is_ascii_control(&self) -> bool { + self.bytes().all(|b| b.is_ascii_control()) + } +} /// An iterator over the escaped version of a byte. /// @@ -684,6 +806,7 @@ mod tests { //! Note that most of these tests are not testing `AsciiExt` methods, but //! test inherent ascii methods of char, u8, str and [u8]. `AsciiExt` is //! just using those methods, though. + use super::AsciiExt; use char::from_u32; #[test] |
