Skip to content

Commit 6bc90aa

Browse files
committed
Rewrite impl FromIterator for Option and Result to use scan.
1 parent 941d92c commit 6bc90aa

File tree

2 files changed

+14
-69
lines changed

2 files changed

+14
-69
lines changed

src/libcore/option.rs

+6-37
Original file line numberDiff line numberDiff line change
@@ -1338,44 +1338,13 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
13381338
/// [`Iterator`]: ../iter/trait.Iterator.html
13391339
#[inline]
13401340
fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> {
1341-
// FIXME(#11084): This could be replaced with Iterator::scan when this
1342-
// performance bug is closed.
1341+
let mut found_none = false;
1342+
let v: V = FromIterator::from_iter(iter.into_iter().scan((), |_, elem| {
1343+
if elem.is_none() { found_none = true; }
1344+
elem
1345+
}));
13431346

1344-
struct Adapter<Iter> {
1345-
iter: Iter,
1346-
found_none: bool,
1347-
}
1348-
1349-
impl<T, Iter: Iterator<Item=Option<T>>> Iterator for Adapter<Iter> {
1350-
type Item = T;
1351-
1352-
#[inline]
1353-
fn next(&mut self) -> Option<T> {
1354-
match self.iter.next() {
1355-
Some(Some(value)) => Some(value),
1356-
Some(None) => {
1357-
self.found_none = true;
1358-
None
1359-
}
1360-
None => None,
1361-
}
1362-
}
1363-
1364-
#[inline]
1365-
fn size_hint(&self) -> (usize, Option<usize>) {
1366-
if self.found_none {
1367-
(0, Some(0))
1368-
} else {
1369-
let (_, upper) = self.iter.size_hint();
1370-
(0, upper)
1371-
}
1372-
}
1373-
}
1374-
1375-
let mut adapter = Adapter { iter: iter.into_iter(), found_none: false };
1376-
let v: V = FromIterator::from_iter(adapter.by_ref());
1377-
1378-
if adapter.found_none {
1347+
if found_none {
13791348
None
13801349
} else {
13811350
Some(v)

src/libcore/result.rs

+8-32
Original file line numberDiff line numberDiff line change
@@ -1232,41 +1232,17 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
12321232
/// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16.
12331233
#[inline]
12341234
fn from_iter<I: IntoIterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> {
1235-
// FIXME(#11084): This could be replaced with Iterator::scan when this
1236-
// performance bug is closed.
1237-
1238-
struct Adapter<Iter, E> {
1239-
iter: Iter,
1240-
err: Option<E>,
1241-
}
1242-
1243-
impl<T, E, Iter: Iterator<Item=Result<T, E>>> Iterator for Adapter<Iter, E> {
1244-
type Item = T;
1245-
1246-
#[inline]
1247-
fn next(&mut self) -> Option<T> {
1248-
match self.iter.next() {
1249-
Some(Ok(value)) => Some(value),
1250-
Some(Err(err)) => {
1251-
self.err = Some(err);
1252-
None
1253-
}
1254-
None => None,
1255-
}
1235+
let mut found_err = None;
1236+
let v: V = FromIterator::from_iter(iter.into_iter().scan((), |_, elem| {
1237+
match elem {
1238+
Err(err) => { found_err = Some(err); None }
1239+
Ok(v) => Some(v)
12561240
}
1241+
}));
12571242

1258-
fn size_hint(&self) -> (usize, Option<usize>) {
1259-
let (_min, max) = self.iter.size_hint();
1260-
(0, max)
1261-
}
1262-
}
1263-
1264-
let mut adapter = Adapter { iter: iter.into_iter(), err: None };
1265-
let v: V = FromIterator::from_iter(adapter.by_ref());
1266-
1267-
match adapter.err {
1243+
match found_err {
12681244
Some(err) => Err(err),
1269-
None => Ok(v),
1245+
None => Ok(v)
12701246
}
12711247
}
12721248
}

0 commit comments

Comments
 (0)