about summary refs log tree commit diff
path: root/src/libcore/str.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore/str.rs')
-rw-r--r--src/libcore/str.rs89
1 files changed, 60 insertions, 29 deletions
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index d0c8558b55d..92f82bd9771 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -31,6 +31,7 @@ use mem;
 use num::Int;
 use option::Option;
 use option::Option::{None, Some};
+use ops::FnMut;
 use ptr::RawPtr;
 use raw::{Repr, Slice};
 use slice::{mod, SlicePrelude};
@@ -136,15 +137,7 @@ impl CharEq for char {
     fn only_ascii(&self) -> bool { (*self as uint) < 128 }
 }
 
-impl<'a> CharEq for |char|: 'a -> bool {
-    #[inline]
-    fn matches(&mut self, c: char) -> bool { (*self)(c) }
-
-    #[inline]
-    fn only_ascii(&self) -> bool { false }
-}
-
-impl CharEq for extern "Rust" fn(char) -> bool {
+impl<F> CharEq for F where F: FnMut(char) -> bool {
     #[inline]
     fn matches(&mut self, c: char) -> bool { (*self)(c) }
 
@@ -323,8 +316,7 @@ impl<'a> DoubleEndedIterator<(uint, char)> for CharOffsets<'a> {
 
 /// External iterator for a string's bytes.
 /// Use with the `std::iter` module.
-pub type Bytes<'a> =
-    Map<'a, &'a u8, u8, slice::Items<'a, u8>>;
+pub type Bytes<'a> = Map<&'a u8, u8, slice::Items<'a, u8>, fn(&u8) -> u8>;
 
 /// An iterator over the substrings of a string, separated by `sep`.
 #[deriving(Clone)]
@@ -349,8 +341,7 @@ pub struct CharSplitsN<'a, Sep> {
 }
 
 /// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
-pub type AnyLines<'a> =
-    Map<'a, &'a str, &'a str, CharSplits<'a, char>>;
+pub type AnyLines<'a> = Map<&'a str, &'a str, CharSplits<'a, char>, fn(&str) -> &str>;
 
 impl<'a, Sep> CharSplits<'a, Sep> {
     #[inline]
@@ -1361,10 +1352,13 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
     /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
+    /// let v: Vec<&str> = "abc1def2ghi".split(|&: c: char| c.is_numeric()).collect();
     /// assert_eq!(v, vec!["abc", "def", "ghi"]);
     ///
     /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
@@ -1372,6 +1366,7 @@ pub trait StrPrelude for Sized? {
     ///
     /// let v: Vec<&str> = "".split('X').collect();
     /// assert_eq!(v, vec![""]);
+    /// # }
     /// ```
     fn split<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>;
 
@@ -1382,10 +1377,13 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect();
     /// assert_eq!(v, vec!["Mary", "had", "a little lambda"]);
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |c: char| c.is_numeric()).collect();
+    /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |&: c: char| c.is_numeric()).collect();
     /// assert_eq!(v, vec!["abc", "def2ghi"]);
     ///
     /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(2, 'X').collect();
@@ -1396,6 +1394,7 @@ pub trait StrPrelude for Sized? {
     ///
     /// let v: Vec<&str> = "".splitn(1, 'X').collect();
     /// assert_eq!(v, vec![""]);
+    /// # }
     /// ```
     fn splitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
 
@@ -1408,6 +1407,9 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
     /// assert_eq!(v, vec!["A", "B"]);
     ///
@@ -1417,11 +1419,12 @@ pub trait StrPrelude for Sized? {
     /// let v: Vec<&str> = "Mary had a little lamb".split(' ').rev().collect();
     /// assert_eq!(v, vec!["lamb", "little", "a", "had", "Mary"]);
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).rev().collect();
+    /// let v: Vec<&str> = "abc1def2ghi".split(|&: c: char| c.is_numeric()).rev().collect();
     /// assert_eq!(v, vec!["ghi", "def", "abc"]);
     ///
     /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').rev().collect();
     /// assert_eq!(v, vec!["leopard", "tiger", "", "lion"]);
+    /// # }
     /// ```
     fn split_terminator<'a, Sep: CharEq>(&'a self, sep: Sep) -> CharSplits<'a, Sep>;
 
@@ -1432,14 +1435,18 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect();
     /// assert_eq!(v, vec!["lamb", "little", "Mary had a"]);
     ///
-    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |c: char| c.is_numeric()).collect();
+    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |&: c: char| c.is_numeric()).collect();
     /// assert_eq!(v, vec!["ghi", "abc1def"]);
     ///
     /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
     /// assert_eq!(v, vec!["leopard", "tiger", "lionX"]);
+    /// # }
     /// ```
     fn rsplitn<'a, Sep: CharEq>(&'a self, count: uint, sep: Sep) -> CharSplitsN<'a, Sep>;
 
@@ -1650,10 +1657,14 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar")
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!("12foo1bar12".trim_chars(x), "foo1bar")
-    /// assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_numeric()), "foo1bar")
+    /// assert_eq!("123foo1bar123".trim_chars(|&: c: char| c.is_numeric()), "foo1bar")
+    /// # }
     /// ```
     fn trim_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
 
@@ -1666,10 +1677,14 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11")
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!("12foo1bar12".trim_left_chars(x), "foo1bar12")
-    /// assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_numeric()), "foo1bar123")
+    /// assert_eq!("123foo1bar123".trim_left_chars(|&: c: char| c.is_numeric()), "foo1bar123")
+    /// # }
     /// ```
     fn trim_left_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
 
@@ -1682,10 +1697,14 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar")
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!("12foo1bar12".trim_right_chars(x), "12foo1bar")
-    /// assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_numeric()), "123foo1bar")
+    /// assert_eq!("123foo1bar123".trim_right_chars(|&: c: char| c.is_numeric()), "123foo1bar")
+    /// # }
     /// ```
     fn trim_right_chars<'a, C: CharEq>(&'a self, to_trim: C) -> &'a str;
 
@@ -1826,17 +1845,21 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let s = "Löwe 老虎 Léopard";
     ///
     /// assert_eq!(s.find('L'), Some(0));
     /// assert_eq!(s.find('é'), Some(14));
     ///
     /// // the first space
-    /// assert_eq!(s.find(|c: char| c.is_whitespace()), Some(5));
+    /// assert_eq!(s.find(|&: c: char| c.is_whitespace()), Some(5));
     ///
     /// // neither are found
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!(s.find(x), None);
+    /// # }
     /// ```
     fn find<C: CharEq>(&self, search: C) -> Option<uint>;
 
@@ -1851,17 +1874,21 @@ pub trait StrPrelude for Sized? {
     /// # Example
     ///
     /// ```rust
+    /// # #![feature(unboxed_closures)]
+    ///
+    /// # fn main() {
     /// let s = "Löwe 老虎 Léopard";
     ///
     /// assert_eq!(s.rfind('L'), Some(13));
     /// assert_eq!(s.rfind('é'), Some(14));
     ///
     /// // the second space
-    /// assert_eq!(s.rfind(|c: char| c.is_whitespace()), Some(12));
+    /// assert_eq!(s.rfind(|&: c: char| c.is_whitespace()), Some(12));
     ///
     /// // searches for an occurrence of either `1` or `2`, but neither are found
     /// let x: &[_] = &['1', '2'];
     /// assert_eq!(s.rfind(x), None);
+    /// # }
     /// ```
     fn rfind<C: CharEq>(&self, search: C) -> Option<uint>;
 
@@ -1980,7 +2007,9 @@ impl StrPrelude for str {
 
     #[inline]
     fn bytes(&self) -> Bytes {
-        self.as_bytes().iter().map(|&b| b)
+        fn deref(&x: &u8) -> u8 { x }
+
+        self.as_bytes().iter().map(deref)
     }
 
     #[inline]
@@ -2053,11 +2082,13 @@ impl StrPrelude for str {
     }
 
     fn lines_any(&self) -> AnyLines {
-        self.lines().map(|line| {
+        fn f(line: &str) -> &str {
             let l = line.len();
             if l > 0 && line.as_bytes()[l - 1] == b'\r' { line.slice(0, l - 1) }
             else { line }
-        })
+        }
+
+        self.lines().map(f)
     }
 
     #[inline]
@@ -2140,11 +2171,11 @@ impl StrPrelude for str {
 
     #[inline]
     fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
-        let cur = match self.find(|c: char| !to_trim.matches(c)) {
+        let cur = match self.find(|&mut: c: char| !to_trim.matches(c)) {
             None => "",
             Some(i) => unsafe { self.slice_unchecked(i, self.len()) }
         };
-        match cur.rfind(|c: char| !to_trim.matches(c)) {
+        match cur.rfind(|&mut: c: char| !to_trim.matches(c)) {
             None => "",
             Some(i) => {
                 let right = cur.char_range_at(i).next;
@@ -2155,7 +2186,7 @@ impl StrPrelude for str {
 
     #[inline]
     fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
-        match self.find(|c: char| !to_trim.matches(c)) {
+        match self.find(|&mut: c: char| !to_trim.matches(c)) {
             None => "",
             Some(first) => unsafe { self.slice_unchecked(first, self.len()) }
         }
@@ -2163,7 +2194,7 @@ impl StrPrelude for str {
 
     #[inline]
     fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &str {
-        match self.rfind(|c: char| !to_trim.matches(c)) {
+        match self.rfind(|&mut: c: char| !to_trim.matches(c)) {
             None => "",
             Some(last) => {
                 let next = self.char_range_at(last).next;