Skip to content

Commit 630627c

Browse files
author
blake2-ppc
committed
std: Implement RandomAccessIterator for iterator adaptors
Implement RAI where possible for iterator adaptors such as Map, Enumerate, Skip, Take, Zip, Cycle (all of the requiring that the adapted iterator also implements RAI).
1 parent 5d4af58 commit 630627c

File tree

1 file changed

+142
-18
lines changed

1 file changed

+142
-18
lines changed

src/libstd/iterator.rs

Lines changed: 142 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,30 @@ impl<A, T: Clone + Iterator<A>> Iterator<A> for Cycle<T> {
811811
}
812812
}
813813

814+
impl<A, T: Clone + RandomAccessIterator<A>> RandomAccessIterator<A> for Cycle<T> {
815+
#[inline]
816+
fn indexable(&self) -> uint {
817+
if self.orig.indexable() > 0 {
818+
uint::max_value
819+
} else {
820+
0
821+
}
822+
}
823+
824+
#[inline]
825+
fn idx(&self, index: uint) -> Option<A> {
826+
let liter = self.iter.indexable();
827+
let lorig = self.orig.indexable();
828+
if lorig == 0 {
829+
None
830+
} else if index < liter {
831+
self.iter.idx(index)
832+
} else {
833+
self.orig.idx((index - liter) % lorig)
834+
}
835+
}
836+
}
837+
814838
/// An iterator which strings two iterators together
815839
#[deriving(Clone)]
816840
pub struct Chain<T, U> {
@@ -924,20 +948,44 @@ impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for Zip<T, U> {
924948
}
925949
}
926950

951+
impl<A, B, T: RandomAccessIterator<A>, U: RandomAccessIterator<B>>
952+
RandomAccessIterator<(A, B)> for Zip<T, U> {
953+
#[inline]
954+
fn indexable(&self) -> uint {
955+
cmp::min(self.a.indexable(), self.b.indexable())
956+
}
957+
958+
#[inline]
959+
fn idx(&self, index: uint) -> Option<(A, B)> {
960+
match (self.a.idx(index), self.b.idx(index)) {
961+
(Some(x), Some(y)) => Some((x, y)),
962+
_ => None
963+
}
964+
}
965+
}
966+
927967
/// An iterator which maps the values of `iter` with `f`
928968
pub struct Map<'self, A, B, T> {
929969
priv iter: T,
930970
priv f: &'self fn(A) -> B
931971
}
932972

933-
impl<'self, A, B, T: Iterator<A>> Iterator<B> for Map<'self, A, B, T> {
973+
impl<'self, A, B, T> Map<'self, A, B, T> {
934974
#[inline]
935-
fn next(&mut self) -> Option<B> {
936-
match self.iter.next() {
975+
fn do_map(&self, elt: Option<A>) -> Option<B> {
976+
match elt {
937977
Some(a) => Some((self.f)(a)),
938978
_ => None
939979
}
940980
}
981+
}
982+
983+
impl<'self, A, B, T: Iterator<A>> Iterator<B> for Map<'self, A, B, T> {
984+
#[inline]
985+
fn next(&mut self) -> Option<B> {
986+
let next = self.iter.next();
987+
self.do_map(next)
988+
}
941989

942990
#[inline]
943991
fn size_hint(&self) -> (uint, Option<uint>) {
@@ -949,10 +997,21 @@ impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
949997
for Map<'self, A, B, T> {
950998
#[inline]
951999
fn next_back(&mut self) -> Option<B> {
952-
match self.iter.next_back() {
953-
Some(a) => Some((self.f)(a)),
954-
_ => None
955-
}
1000+
let next = self.iter.next_back();
1001+
self.do_map(next)
1002+
}
1003+
}
1004+
1005+
impl<'self, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B>
1006+
for Map<'self, A, B, T> {
1007+
#[inline]
1008+
fn indexable(&self) -> uint {
1009+
self.iter.indexable()
1010+
}
1011+
1012+
#[inline]
1013+
fn idx(&self, index: uint) -> Option<B> {
1014+
self.do_map(self.iter.idx(index))
9561015
}
9571016
}
9581017

@@ -1069,6 +1128,21 @@ impl<A, T: Iterator<A>> Iterator<(uint, A)> for Enumerate<T> {
10691128
}
10701129
}
10711130

1131+
impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<(uint, A)> for Enumerate<T> {
1132+
#[inline]
1133+
fn indexable(&self) -> uint {
1134+
self.iter.indexable()
1135+
}
1136+
1137+
#[inline]
1138+
fn idx(&self, index: uint) -> Option<(uint, A)> {
1139+
match self.iter.idx(index) {
1140+
Some(a) => Some((self.count + index, a)),
1141+
_ => None,
1142+
}
1143+
}
1144+
}
1145+
10721146
/// An iterator which rejects elements while `predicate` is true
10731147
pub struct SkipWhile<'self, A, T> {
10741148
priv iter: T,
@@ -1189,6 +1263,27 @@ impl<A, T: Iterator<A>> Iterator<A> for Skip<T> {
11891263
}
11901264
}
11911265

1266+
impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Skip<T> {
1267+
#[inline]
1268+
fn indexable(&self) -> uint {
1269+
let N = self.iter.indexable();
1270+
if N < self.n {
1271+
0
1272+
} else {
1273+
N - self.n
1274+
}
1275+
}
1276+
1277+
#[inline]
1278+
fn idx(&self, index: uint) -> Option<A> {
1279+
if index >= self.indexable() {
1280+
None
1281+
} else {
1282+
self.iter.idx(index + self.n)
1283+
}
1284+
}
1285+
}
1286+
11921287
/// An iterator which only iterates over the first `n` iterations of `iter`.
11931288
#[deriving(Clone)]
11941289
pub struct Take<T> {
@@ -1223,6 +1318,23 @@ impl<A, T: Iterator<A>> Iterator<A> for Take<T> {
12231318
}
12241319
}
12251320

1321+
impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Take<T> {
1322+
#[inline]
1323+
fn indexable(&self) -> uint {
1324+
cmp::min(self.iter.indexable(), self.n)
1325+
}
1326+
1327+
#[inline]
1328+
fn idx(&self, index: uint) -> Option<A> {
1329+
if index >= self.n {
1330+
None
1331+
} else {
1332+
self.iter.idx(index)
1333+
}
1334+
}
1335+
}
1336+
1337+
12261338
/// An iterator to maintain state while iterating another iterator
12271339
pub struct Scan<'self, A, B, T, St> {
12281340
priv iter: T,
@@ -1311,17 +1423,23 @@ pub struct Peek<'self, A, T> {
13111423
priv f: &'self fn(&A)
13121424
}
13131425

1314-
impl<'self, A, T: Iterator<A>> Iterator<A> for Peek<'self, A, T> {
1426+
impl<'self, A, T> Peek<'self, A, T> {
13151427
#[inline]
1316-
fn next(&mut self) -> Option<A> {
1317-
let next = self.iter.next();
1318-
1319-
match next {
1428+
fn do_peek(&self, elt: Option<A>) -> Option<A> {
1429+
match elt {
13201430
Some(ref a) => (self.f)(a),
13211431
None => ()
13221432
}
13231433

1324-
next
1434+
elt
1435+
}
1436+
}
1437+
1438+
impl<'self, A, T: Iterator<A>> Iterator<A> for Peek<'self, A, T> {
1439+
#[inline]
1440+
fn next(&mut self) -> Option<A> {
1441+
let next = self.iter.next();
1442+
self.do_peek(next)
13251443
}
13261444

13271445
#[inline]
@@ -1334,13 +1452,19 @@ impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Peek<'self,
13341452
#[inline]
13351453
fn next_back(&mut self) -> Option<A> {
13361454
let next = self.iter.next_back();
1455+
self.do_peek(next)
1456+
}
1457+
}
13371458

1338-
match next {
1339-
Some(ref a) => (self.f)(a),
1340-
None => ()
1341-
}
1459+
impl<'self, A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Peek<'self, A, T> {
1460+
#[inline]
1461+
fn indexable(&self) -> uint {
1462+
self.iter.indexable()
1463+
}
13421464

1343-
next
1465+
#[inline]
1466+
fn idx(&self, index: uint) -> Option<A> {
1467+
self.do_peek(self.iter.idx(index))
13441468
}
13451469
}
13461470

0 commit comments

Comments
 (0)