Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std: Changing the meaning of the count to splitn #23951

Merged
merged 1 commit into from
Apr 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiletest/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> = nv
.splitn(1, '=')
.splitn(2, '=')
.map(|s| s.to_string())
.collect();

Expand Down
24 changes: 18 additions & 6 deletions src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,17 +328,20 @@ impl<T> [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]`,
/// `[20, 60, 50]`):
///
/// ```
/// 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);
/// }
/// ```
Expand All @@ -349,18 +352,21 @@ impl<T> [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
/// by 3 (i.e. `[50]`, `[10, 40, 30, 20]`):
///
/// ```
/// 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);
/// }
/// ```
Expand Down Expand Up @@ -626,8 +632,11 @@ impl<T> [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<F>(&mut self, n: usize, pred: F) -> SplitNMut<T, F>
Expand All @@ -636,9 +645,12 @@ impl<T> [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<F>(&mut self, n: usize, pred: F) -> RSplitNMut<T, F>
Expand Down
28 changes: 17 additions & 11 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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")]
Expand Down Expand Up @@ -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")]
Expand Down
25 changes: 13 additions & 12 deletions src/libcollectionstest/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -867,37 +867,37 @@ 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::<Vec<_>>(),
assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
splits);
let splits: &[&[_]] = &[&[1], &[3,4,5]];
assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
assert_eq!(xs.splitn(2, |x| *x % 2 == 0).collect::<Vec<_>>(),
splits);
let splits: &[&[_]] = &[&[], &[], &[], &[4,5]];
assert_eq!(xs.splitn(3, |_| true).collect::<Vec<_>>(),
assert_eq!(xs.splitn(4, |_| true).collect::<Vec<_>>(),
splits);

let xs: &[i32] = &[];
let splits: &[&[i32]] = &[&[]];
assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<_>>(), splits);
assert_eq!(xs.splitn(2, |x| *x == 5).collect::<Vec<_>>(), splits);
}

#[test]
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::<Vec<_>>(),
assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
splits);
let splits: &[&mut[_]] = &[&mut [1], &mut [3,4,5]];
assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
assert_eq!(xs.splitn_mut(2, |x| *x % 2 == 0).collect::<Vec<_>>(),
splits);
let splits: &[&mut[_]] = &[&mut [], &mut [], &mut [], &mut [4,5]];
assert_eq!(xs.splitn_mut(3, |_| true).collect::<Vec<_>>(),
assert_eq!(xs.splitn_mut(4, |_| true).collect::<Vec<_>>(),
splits);

let xs: &mut [i32] = &mut [];
let splits: &[&mut[i32]] = &[&mut []];
assert_eq!(xs.splitn_mut(1, |x| *x == 5).collect::<Vec<_>>(),
assert_eq!(xs.splitn_mut(2, |x| *x == 5).collect::<Vec<_>>(),
splits);
}

Expand Down Expand Up @@ -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::<Vec<_>>(),
assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
splits);
let splits: &[&[_]] = &[&[5], &[1,2,3]];
assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
assert_eq!(xs.rsplitn(2, |x| *x % 2 == 0).collect::<Vec<_>>(),
splits);
let splits: &[&[_]] = &[&[], &[], &[], &[1,2]];
assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<_>>(),
assert_eq!(xs.rsplitn(4, |_| true).collect::<Vec<_>>(),
splits);

let xs: &[i32] = &[];
let splits: &[&[i32]] = &[&[]];
assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[i32]>>(), splits);
assert_eq!(xs.rsplitn(2, |x| *x == 5).collect::<Vec<&[i32]>>(), splits);
assert!(xs.rsplitn(0, |x| *x % 2 == 0).next().is_none());
}

#[test]
Expand Down
14 changes: 7 additions & 7 deletions src/libcollectionstest/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]);
}

Expand Down Expand Up @@ -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"]);
}

Expand Down
14 changes: 8 additions & 6 deletions src/libcore/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1126,18 +1126,20 @@ impl<T, I: SplitIter<Item=T>> Iterator for GenericSplitN<I> {

#[inline]
fn next(&mut self) -> Option<T> {
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<usize>) {
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)))
}
}

Expand Down
20 changes: 9 additions & 11 deletions src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down Expand Up @@ -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() }
}
}
}
Expand Down Expand Up @@ -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() }
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/libcoretest/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"]);
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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("-", "_");
Expand Down Expand Up @@ -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) |
Expand Down Expand Up @@ -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"),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_driver/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub enum PpMode {
pub fn parse_pretty(sess: &Session,
name: &str,
extended: bool) -> (PpMode, Option<UserIdentifiedItem>) {
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) {
Expand Down
Loading