diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 9612c0e06a3..f5505b6e83a 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -311,7 +311,7 @@ fn parse_exec_env(line: &str) -> Option<(String, String)> { parse_name_value_directive(line, "exec-env").map(|nv| { // nv is either FOO or FOO=BAR let mut strs: Vec = nv - .splitn(1, '=') + .splitn(2, '=') .map(|s| s.to_string()) .collect(); diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 4599aff000d..d35173cbebf 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -328,9 +328,12 @@ impl [T] { } /// Returns an iterator over subslices separated by elements that match - /// `pred`, limited to splitting at most `n` times. The matched element is + /// `pred`, limited to returning at most `n` items. The matched element is /// not contained in the subslices. /// + /// The last element returned, if any, will contain the remainder of the + /// slice. + /// /// # Examples /// /// Print the slice split once by numbers divisible by 3 (i.e. `[10, 40]`, @@ -338,7 +341,7 @@ impl [T] { /// /// ``` /// let v = [10, 40, 30, 20, 60, 50]; - /// for group in v.splitn(1, |num| *num % 3 == 0) { + /// for group in v.splitn(2, |num| *num % 3 == 0) { /// println!("{:?}", group); /// } /// ``` @@ -349,10 +352,13 @@ impl [T] { } /// Returns an iterator over subslices separated by elements that match - /// `pred` limited to splitting at most `n` times. This starts at the end of + /// `pred` limited to returning at most `n` items. This starts at the end of /// the slice and works backwards. The matched element is not contained in /// the subslices. /// + /// The last element returned, if any, will contain the remainder of the + /// slice. + /// /// # Examples /// /// Print the slice split once, starting from the end, by numbers divisible @@ -360,7 +366,7 @@ impl [T] { /// /// ``` /// let v = [10, 40, 30, 20, 60, 50]; - /// for group in v.rsplitn(1, |num| *num % 3 == 0) { + /// for group in v.rsplitn(2, |num| *num % 3 == 0) { /// println!("{:?}", group); /// } /// ``` @@ -626,8 +632,11 @@ impl [T] { } /// Returns an iterator over subslices separated by elements that match - /// `pred`, limited to splitting at most `n` times. The matched element is + /// `pred`, limited to returning at most `n` items. The matched element is /// not contained in the subslices. + /// + /// The last element returned, if any, will contain the remainder of the + /// slice. #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn splitn_mut(&mut self, n: usize, pred: F) -> SplitNMut @@ -636,9 +645,12 @@ impl [T] { } /// Returns an iterator over subslices separated by elements that match - /// `pred` limited to splitting at most `n` times. This starts at the end of + /// `pred` limited to returning at most `n` items. This starts at the end of /// the slice and works backwards. The matched element is not contained in /// the subslices. + /// + /// The last element returned, if any, will contain the remainder of the + /// slice. #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn rsplitn_mut(&mut self, n: usize, pred: F) -> RSplitNMut diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index f8f2909291f..c22b6fb9286 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -610,24 +610,27 @@ impl str { core_str::StrExt::split(&self[..], pat) } - /// An iterator over substrings of `self`, separated by characters matched by a pattern, - /// restricted to splitting at most `count` times. + /// An iterator over substrings of `self`, separated by characters matched + /// by a pattern, returning most `count` items. /// /// The pattern can be a simple `&str`, or a closure that determines /// the split. /// + /// The last element returned, if any, will contain the remainder of the + /// string. + /// /// # Examples /// /// Simple `&str` patterns: /// /// ``` /// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect(); - /// assert_eq!(v, ["Mary", "had", "a little lambda"]); + /// assert_eq!(v, ["Mary", "had a little lambda"]); /// /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(2, 'X').collect(); - /// assert_eq!(v, ["lion", "", "tigerXleopard"]); + /// assert_eq!(v, ["lion", "XtigerXleopard"]); /// - /// let v: Vec<&str> = "abcXdef".splitn(0, 'X').collect(); + /// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect(); /// assert_eq!(v, ["abcXdef"]); /// /// let v: Vec<&str> = "".splitn(1, 'X').collect(); @@ -637,7 +640,7 @@ impl str { /// More complex patterns with a lambda: /// /// ``` - /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |c: char| c.is_numeric()).collect(); + /// let v: Vec<&str> = "abc1def2ghi".splitn(2, |c: char| c.is_numeric()).collect(); /// assert_eq!(v, ["abc", "def2ghi"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -705,25 +708,28 @@ impl str { } /// An iterator over substrings of `self`, separated by a pattern, - /// starting from the end of the string, restricted to splitting - /// at most `count` times. + /// starting from the end of the string, restricted to returning + /// at most `count` items. + /// + /// The last element returned, if any, will contain the remainder of the + /// string. /// /// # Examples /// /// Simple patterns: /// /// ``` - /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect(); + /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect(); /// assert_eq!(v, ["lamb", "little", "Mary had a"]); /// - /// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(1, "::").collect(); + /// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect(); /// assert_eq!(v, ["leopard", "lion::tiger"]); /// ``` /// /// More complex patterns with a lambda: /// /// ``` - /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |c: char| c.is_numeric()).collect(); + /// let v: Vec<&str> = "abc1def2ghi".rsplitn(2, |c: char| c.is_numeric()).collect(); /// assert_eq!(v, ["ghi", "abc1def"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs index 041d9fba57c..9dc12aa5bd9 100644 --- a/src/libcollectionstest/slice.rs +++ b/src/libcollectionstest/slice.rs @@ -867,18 +867,18 @@ fn test_splitnator() { let xs = &[1,2,3,4,5]; let splits: &[&[_]] = &[&[1,2,3,4,5]]; - assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::>(), - splits); - let splits: &[&[_]] = &[&[1], &[3,4,5]]; assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::>(), splits); + let splits: &[&[_]] = &[&[1], &[3,4,5]]; + assert_eq!(xs.splitn(2, |x| *x % 2 == 0).collect::>(), + splits); let splits: &[&[_]] = &[&[], &[], &[], &[4,5]]; - assert_eq!(xs.splitn(3, |_| true).collect::>(), + assert_eq!(xs.splitn(4, |_| true).collect::>(), splits); let xs: &[i32] = &[]; let splits: &[&[i32]] = &[&[]]; - assert_eq!(xs.splitn(1, |x| *x == 5).collect::>(), splits); + assert_eq!(xs.splitn(2, |x| *x == 5).collect::>(), splits); } #[test] @@ -886,18 +886,18 @@ fn test_splitnator_mut() { let xs = &mut [1,2,3,4,5]; let splits: &[&mut[_]] = &[&mut [1,2,3,4,5]]; - assert_eq!(xs.splitn_mut(0, |x| *x % 2 == 0).collect::>(), - splits); - let splits: &[&mut[_]] = &[&mut [1], &mut [3,4,5]]; assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::>(), splits); + let splits: &[&mut[_]] = &[&mut [1], &mut [3,4,5]]; + assert_eq!(xs.splitn_mut(2, |x| *x % 2 == 0).collect::>(), + splits); let splits: &[&mut[_]] = &[&mut [], &mut [], &mut [], &mut [4,5]]; - assert_eq!(xs.splitn_mut(3, |_| true).collect::>(), + assert_eq!(xs.splitn_mut(4, |_| true).collect::>(), splits); let xs: &mut [i32] = &mut []; let splits: &[&mut[i32]] = &[&mut []]; - assert_eq!(xs.splitn_mut(1, |x| *x == 5).collect::>(), + assert_eq!(xs.splitn_mut(2, |x| *x == 5).collect::>(), splits); } @@ -928,18 +928,19 @@ fn test_rsplitnator() { let xs = &[1,2,3,4,5]; let splits: &[&[_]] = &[&[1,2,3,4,5]]; - assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::>(), - splits); - let splits: &[&[_]] = &[&[5], &[1,2,3]]; assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::>(), splits); + let splits: &[&[_]] = &[&[5], &[1,2,3]]; + assert_eq!(xs.rsplitn(2, |x| *x % 2 == 0).collect::>(), + splits); let splits: &[&[_]] = &[&[], &[], &[], &[1,2]]; - assert_eq!(xs.rsplitn(3, |_| true).collect::>(), + assert_eq!(xs.rsplitn(4, |_| true).collect::>(), splits); let xs: &[i32] = &[]; let splits: &[&[i32]] = &[&[]]; - assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::>(), splits); + assert_eq!(xs.rsplitn(2, |x| *x == 5).collect::>(), splits); + assert!(xs.rsplitn(0, |x| *x % 2 == 0).next().is_none()); } #[test] diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs index ed9ee0206b7..495a961fa36 100644 --- a/src/libcollectionstest/str.rs +++ b/src/libcollectionstest/str.rs @@ -885,17 +885,17 @@ fn test_char_indices_revator() { fn test_splitn_char_iterator() { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; - let split: Vec<&str> = data.splitn(3, ' ').collect(); + let split: Vec<&str> = data.splitn(4, ' ').collect(); assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); - let split: Vec<&str> = data.splitn(3, |c: char| c == ' ').collect(); + let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect(); assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); // Unicode - let split: Vec<&str> = data.splitn(3, 'ä').collect(); + let split: Vec<&str> = data.splitn(4, 'ä').collect(); assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); - let split: Vec<&str> = data.splitn(3, |c: char| c == 'ä').collect(); + let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect(); assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); } @@ -928,13 +928,13 @@ fn test_rsplit() { fn test_rsplitn() { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; - let split: Vec<&str> = data.rsplitn(1, ' ').collect(); + let split: Vec<&str> = data.rsplitn(2, ' ').collect(); assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]); - let split: Vec<&str> = data.rsplitn(1, "lämb").collect(); + let split: Vec<&str> = data.rsplitn(2, "lämb").collect(); assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]); - let split: Vec<&str> = data.rsplitn(1, |c: char| c == 'ä').collect(); + let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect(); assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]); } diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index d8856130fab..70e60adf64c 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -1126,18 +1126,20 @@ impl> Iterator for GenericSplitN { #[inline] fn next(&mut self) -> Option { - if self.count == 0 { - self.iter.finish() - } else { - self.count -= 1; - if self.invert { self.iter.next_back() } else { self.iter.next() } + match self.count { + 0 => None, + 1 => { self.count -= 1; self.iter.finish() } + _ => { + self.count -= 1; + if self.invert {self.iter.next_back()} else {self.iter.next()} + } } } #[inline] fn size_hint(&self) -> (usize, Option) { let (lower, upper_opt) = self.iter.size_hint(); - (lower, upper_opt.map(|upper| cmp::min(self.count + 1, upper))) + (lower, upper_opt.map(|upper| cmp::min(self.count, upper))) } } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 934c4515614..23d6a9c1193 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -505,7 +505,7 @@ struct CharSplits<'a, P: Pattern<'a>> { /// splitting at most `count` times. struct CharSplitsN<'a, P: Pattern<'a>> { iter: CharSplits<'a, P>, - /// The number of splits remaining + /// The number of items remaining count: usize, } @@ -612,11 +612,10 @@ impl<'a, P: Pattern<'a>> Iterator for CharSplitsN<'a, P> { #[inline] fn next(&mut self) -> Option<&'a str> { - if self.count != 0 { - self.count -= 1; - self.iter.next() - } else { - self.iter.get_end() + match self.count { + 0 => None, + 1 => { self.count = 0; self.iter.get_end() } + _ => { self.count -= 1; self.iter.next() } } } } @@ -666,11 +665,10 @@ impl<'a, P: Pattern<'a>> Iterator for RCharSplitsN<'a, P> #[inline] fn next(&mut self) -> Option<&'a str> { - if self.count != 0 { - self.count -= 1; - self.iter.next() - } else { - self.iter.get_remainder() + match self.count { + 0 => None, + 1 => { self.count -= 1; self.iter.get_remainder() } + _ => { self.count -= 1; self.iter.next() } } } } diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs index c935b554574..5fce527d979 100644 --- a/src/libcoretest/str.rs +++ b/src/libcoretest/str.rs @@ -65,20 +65,20 @@ fn test_strslice_contains() { fn test_rsplitn_char_iterator() { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; - let mut split: Vec<&str> = data.rsplitn(3, ' ').collect(); + let mut split: Vec<&str> = data.rsplitn(4, ' ').collect(); split.reverse(); assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); - let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect(); + let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect(); split.reverse(); assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); // Unicode - let mut split: Vec<&str> = data.rsplitn(3, 'ä').collect(); + let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect(); split.reverse(); assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); - let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect(); + let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect(); split.reverse(); assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index c67819ab7e3..5a598921195 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -304,7 +304,7 @@ macro_rules! options { { let mut op = $defaultfn(); for option in matches.opt_strs($prefix) { - let mut iter = option.splitn(1, '='); + let mut iter = option.splitn(2, '='); let key = iter.next().unwrap(); let value = iter.next(); let option_to_lookup = key.replace("-", "_"); @@ -958,7 +958,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } let libs = matches.opt_strs("l").into_iter().map(|s| { - let mut parts = s.splitn(1, '='); + let mut parts = s.splitn(2, '='); let kind = parts.next().unwrap(); let (name, kind) = match (parts.next(), kind) { (None, name) | @@ -1010,7 +1010,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let mut externs = HashMap::new(); for arg in &matches.opt_strs("extern") { - let mut parts = arg.splitn(1, '='); + let mut parts = arg.splitn(2, '='); let name = match parts.next() { Some(s) => s, None => early_error("--extern value must not be empty"), diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index fe55ca3b73b..605b486841f 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -74,7 +74,7 @@ pub enum PpMode { pub fn parse_pretty(sess: &Session, name: &str, extended: bool) -> (PpMode, Option) { - let mut split = name.splitn(1, '='); + let mut split = name.splitn(2, '='); let first = split.next().unwrap(); let opt_second = split.next(); let first = match (first, extended) { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 1ff3411f8fc..d1dcfc26008 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -333,7 +333,7 @@ fn acquire_input(input: &str, fn parse_externs(matches: &getopts::Matches) -> Result { let mut externs = HashMap::new(); for arg in &matches.opt_strs("extern") { - let mut parts = arg.splitn(1, '='); + let mut parts = arg.splitn(2, '='); let name = match parts.next() { Some(s) => s, None => { diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index c45230e91ba..886f252fb19 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -441,7 +441,7 @@ impl ToSocketAddrs for str { } // split the string by ':' and convert the second part to u16 - let mut parts_iter = self.rsplitn(1, ':'); + let mut parts_iter = self.rsplitn(2, ':'); let port_str = try_opt!(parts_iter.next(), "invalid socket address"); let host = try_opt!(parts_iter.next(), "invalid socket address"); let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value"); diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 9006ed33654..ee4b572335b 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -406,7 +406,7 @@ fn split_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) { // contents of the encoding and (2) new &OsStr values are produced // only from ASCII-bounded slices of existing &OsStr values. - let mut iter = os_str_as_u8_slice(file).rsplitn(1, |b| *b == b'.'); + let mut iter = os_str_as_u8_slice(file).rsplitn(2, |b| *b == b'.'); let after = iter.next(); let before = iter.next(); if before == Some(b"") { diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 7b13e951b9b..d2220bdec32 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -409,7 +409,7 @@ pub fn env() -> Env { }; fn parse(input: &[u8]) -> (OsString, OsString) { - let mut it = input.splitn(1, |b| *b == b'='); + let mut it = input.splitn(2, |b| *b == b'='); let key = it.next().unwrap().to_vec(); let default: &[u8] = &[]; let val = it.next().unwrap_or(default).to_vec();