about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-10-17 09:56:27 -0700
committerbors <bors@rust-lang.org>2013-10-17 09:56:27 -0700
commitd4a32386f3b61a4997de54ed00c0a80fd07ecc75 (patch)
treed766986b7eed566a705dd6f8fd135cb10614a881
parent2cb96a4eaf55cdf7f08e3493cf2953278b8acc43 (diff)
parent87a2d032ff6fe74e97348189f95a3a91fd9e228e (diff)
downloadrust-d4a32386f3b61a4997de54ed00c0a80fd07ecc75.tar.gz
rust-d4a32386f3b61a4997de54ed00c0a80fd07ecc75.zip
auto merge of #9907 : kballard/rust/vec_ends_with, r=alexcrichton
-rw-r--r--src/librustc/back/rpath.rs7
-rw-r--r--src/librustpkg/tests.rs8
-rw-r--r--src/libstd/str.rs25
-rw-r--r--src/libstd/vec.rs50
-rw-r--r--src/test/run-pass/tempfile.rs5
5 files changed, 59 insertions, 36 deletions
diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs
index 0626ec0ece0..faf8dd25186 100644
--- a/src/librustc/back/rpath.rs
+++ b/src/librustc/back/rpath.rs
@@ -189,12 +189,9 @@ mod test {
         let mut d = Path::new(env!("CFG_PREFIX"));
         d.push("lib/rustc/triple/lib");
         debug2!("test_prefix_path: {} vs. {}",
-               res.to_str(),
+               res,
                d.display());
-        assert!(ends_with(res.as_bytes(), d.as_vec()));
-        fn ends_with(v: &[u8], needle: &[u8]) -> bool {
-            v.len() >= needle.len() && v.slice_from(v.len()-needle.len()) == needle
-        }
+        assert!(res.as_bytes().ends_with(d.as_vec()));
     }
 
     #[test]
diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs
index d367399c0bf..0fe16862518 100644
--- a/src/librustpkg/tests.rs
+++ b/src/librustpkg/tests.rs
@@ -217,10 +217,6 @@ fn is_read_only(p: &Path) -> bool {
     }
 }
 
-fn ends_with(v: &[u8], needle: &[u8]) -> bool {
-    v.len() >= needle.len() && v.slice_from(v.len() - needle.len()) == needle
-}
-
 fn test_sysroot() -> Path {
     // Totally gross hack but it's just for test cases.
     // Infer the sysroot from the exe name and pray that it's right.
@@ -747,7 +743,7 @@ fn test_package_version() {
                                              &ws) {
         Some(p) => {
             let suffix = format!("0.4{}", os::consts::DLL_SUFFIX);
-            ends_with(p.as_vec(), suffix.as_bytes())
+            p.as_vec().ends_with(suffix.as_bytes())
         }
         None    => false
     });
@@ -785,7 +781,7 @@ fn test_package_request_version() {
         Some(p) => {
             debug2!("installed: {}", p.display());
             let suffix = format!("0.3{}", os::consts::DLL_SUFFIX);
-            ends_with(p.as_vec(), suffix.as_bytes())
+            p.as_vec().ends_with(suffix.as_bytes())
         }
         None    => false
     });
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index decfbb0785c..5c6974de17d 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -828,17 +828,6 @@ pub fn eq(a: &~str, b: &~str) -> bool {
 }
 
 /*
-Section: Searching
-*/
-
-// Utility used by various searching functions
-fn match_at<'a,'b>(haystack: &'a str, needle: &'b str, at: uint) -> bool {
-    let mut i = at;
-    for c in needle.byte_iter() { if haystack[i] != c { return false; } i += 1u; }
-    return true;
-}
-
-/*
 Section: Misc
 */
 
@@ -2018,18 +2007,16 @@ impl<'self> StrSlice<'self> for &'self str {
         }
     }
 
+    #[inline]
     fn starts_with<'a>(&self, needle: &'a str) -> bool {
-        let (self_len, needle_len) = (self.len(), needle.len());
-        if needle_len == 0u { true }
-        else if needle_len > self_len { false }
-        else { match_at(*self, needle, 0u) }
+        let n = needle.len();
+        self.len() >= n && needle == self.slice_to(n)
     }
 
+    #[inline]
     fn ends_with(&self, needle: &str) -> bool {
-        let (self_len, needle_len) = (self.len(), needle.len());
-        if needle_len == 0u { true }
-        else if needle_len > self_len { false }
-        else { match_at(*self, needle, self_len - needle_len) }
+        let (m, n) = (self.len(), needle.len());
+        m >= n && needle == self.slice_from(m - n)
     }
 
     fn escape_default(&self) -> ~str {
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 3962df8e3bd..17dcced9485 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -1173,6 +1173,12 @@ pub trait ImmutableEqVector<T:Eq> {
 
     /// Return true if a vector contains an element with the given value
     fn contains(&self, x: &T) -> bool;
+
+    /// Returns true if `needle` is a prefix of the vector.
+    fn starts_with(&self, needle: &[T]) -> bool;
+
+    /// Returns true if `needle` is a suffix of the vector.
+    fn ends_with(&self, needle: &[T]) -> bool;
 }
 
 impl<'self,T:Eq> ImmutableEqVector<T> for &'self [T] {
@@ -1186,9 +1192,21 @@ impl<'self,T:Eq> ImmutableEqVector<T> for &'self [T] {
         self.iter().rposition(|x| *x == *t)
     }
 
+    #[inline]
     fn contains(&self, x: &T) -> bool {
-        for elt in self.iter() { if *x == *elt { return true; } }
-        false
+        self.iter().any(|elt| *x == *elt)
+    }
+
+    #[inline]
+    fn starts_with(&self, needle: &[T]) -> bool {
+        let n = needle.len();
+        self.len() >= n && needle == self.slice_to(n)
+    }
+
+    #[inline]
+    fn ends_with(&self, needle: &[T]) -> bool {
+        let (m, n) = (self.len(), needle.len());
+        m >= n && needle == self.slice_from(m - n)
     }
 }
 
@@ -3828,6 +3846,34 @@ mod tests {
         assert_eq!(xs.capacity(), 100);
         assert_eq!(xs, range(0, 100).to_owned_vec());
     }
+
+    #[test]
+    fn test_starts_with() {
+        assert!(bytes!("foobar").starts_with(bytes!("foo")));
+        assert!(!bytes!("foobar").starts_with(bytes!("oob")));
+        assert!(!bytes!("foobar").starts_with(bytes!("bar")));
+        assert!(!bytes!("foo").starts_with(bytes!("foobar")));
+        assert!(!bytes!("bar").starts_with(bytes!("foobar")));
+        assert!(bytes!("foobar").starts_with(bytes!("foobar")));
+        let empty: &[u8] = [];
+        assert!(empty.starts_with(empty));
+        assert!(!empty.starts_with(bytes!("foo")));
+        assert!(bytes!("foobar").starts_with(empty));
+    }
+
+    #[test]
+    fn test_ends_with() {
+        assert!(bytes!("foobar").ends_with(bytes!("bar")));
+        assert!(!bytes!("foobar").ends_with(bytes!("oba")));
+        assert!(!bytes!("foobar").ends_with(bytes!("foo")));
+        assert!(!bytes!("foo").ends_with(bytes!("foobar")));
+        assert!(!bytes!("bar").ends_with(bytes!("foobar")));
+        assert!(bytes!("foobar").ends_with(bytes!("foobar")));
+        let empty: &[u8] = [];
+        assert!(empty.ends_with(empty));
+        assert!(!empty.ends_with(bytes!("foo")));
+        assert!(bytes!("foobar").ends_with(empty));
+    }
 }
 
 #[cfg(test)]
diff --git a/src/test/run-pass/tempfile.rs b/src/test/run-pass/tempfile.rs
index 837194fcf9f..5d12f4e8817 100644
--- a/src/test/run-pass/tempfile.rs
+++ b/src/test/run-pass/tempfile.rs
@@ -30,13 +30,10 @@ fn test_tempdir() {
     let path = {
         let p = TempDir::new_in(&Path::new("."), "foobar").unwrap();
         let p = p.path();
-        assert!(ends_with(p.as_vec(), bytes!("foobar")));
+        assert!(p.as_vec().ends_with(bytes!("foobar")));
         p.clone()
     };
     assert!(!os::path_exists(&path));
-    fn ends_with(v: &[u8], needle: &[u8]) -> bool {
-        v.len() >= needle.len() && v.slice_from(v.len()-needle.len()) == needle
-    }
 }
 
 fn test_rm_tempdir() {