diff options
Diffstat (limited to 'src/libcore/str.rs')
| -rw-r--r-- | src/libcore/str.rs | 89 |
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; |
