about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2017-11-29 18:37:44 +0800
committerGitHub <noreply@github.com>2017-11-29 18:37:44 +0800
commit963ab91dd40a57c061229f006dcf8ce271d89664 (patch)
tree40c0aaa5494f132492f7fb1fdc94cec54723f612 /src/libstd
parent0ec3aee569a8a34117d265e48eb980a955a2186d (diff)
parentc5aad96739228e8e05b597b32ee7126c843b7228 (diff)
downloadrust-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.rs209
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]