Skip to content

Commit c64f963

Browse files
committed
Implement .size_hint() on new vec iterators
1 parent 8fff3f4 commit c64f963

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

src/libstd/vec.rs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
6565
use cmp;
6666
use iterator::*;
6767
use libc::c_void;
68-
use num::Zero;
68+
use num::{Integer, Zero, CheckedAdd, Saturating};
6969
use option::{None, Option, Some};
7070
use ptr::to_unsafe_ptr;
7171
use ptr;
@@ -209,6 +209,7 @@ pub struct SplitIterator<'self, T> {
209209
}
210210

211211
impl<'self, T> Iterator<&'self [T]> for SplitIterator<'self, T> {
212+
#[inline]
212213
fn next(&mut self) -> Option<&'self [T]> {
213214
if self.finished { return None; }
214215

@@ -230,6 +231,21 @@ impl<'self, T> Iterator<&'self [T]> for SplitIterator<'self, T> {
230231
}
231232
}
232233
}
234+
235+
#[inline]
236+
fn size_hint(&self) -> (uint, Option<uint>) {
237+
if self.finished {
238+
return (0, Some(0))
239+
}
240+
// if the predicate doesn't match anything, we yield one slice
241+
// if it matches every element, we yield N+1 empty slices where
242+
// N is either the number of elements or the number of splits.
243+
match (self.v.len(), self.n) {
244+
(0,_) => (1, Some(1)),
245+
(_,0) => (1, Some(1)),
246+
(l,n) => (1, cmp::min(l,n).checked_add(&1u))
247+
}
248+
}
233249
}
234250

235251
/// An iterator over the slices of a vector separated by elements that
@@ -242,6 +258,7 @@ pub struct RSplitIterator<'self, T> {
242258
}
243259

244260
impl<'self, T> Iterator<&'self [T]> for RSplitIterator<'self, T> {
261+
#[inline]
245262
fn next(&mut self) -> Option<&'self [T]> {
246263
if self.finished { return None; }
247264

@@ -263,6 +280,18 @@ impl<'self, T> Iterator<&'self [T]> for RSplitIterator<'self, T> {
263280
}
264281
}
265282
}
283+
284+
#[inline]
285+
fn size_hint(&self) -> (uint, Option<uint>) {
286+
if self.finished {
287+
return (0, Some(0))
288+
}
289+
match (self.v.len(), self.n) {
290+
(0,_) => (1, Some(1)),
291+
(_,0) => (1, Some(1)),
292+
(l,n) => (1, cmp::min(l,n).checked_add(&1u))
293+
}
294+
}
266295
}
267296

268297
// Appending
@@ -453,6 +482,7 @@ pub struct WindowIter<'self, T> {
453482
}
454483

455484
impl<'self, T> Iterator<&'self [T]> for WindowIter<'self, T> {
485+
#[inline]
456486
fn next(&mut self) -> Option<&'self [T]> {
457487
if self.size > self.v.len() {
458488
None
@@ -462,6 +492,16 @@ impl<'self, T> Iterator<&'self [T]> for WindowIter<'self, T> {
462492
ret
463493
}
464494
}
495+
496+
#[inline]
497+
fn size_hint(&self) -> (uint, Option<uint>) {
498+
if self.size > self.v.len() {
499+
(0, Some(0))
500+
} else {
501+
let x = self.v.len() - self.size;
502+
(x.saturating_add(1), x.checked_add(&1u))
503+
}
504+
}
465505
}
466506

467507
/// An iterator over a vector in (non-overlapping) chunks (`size`
@@ -476,6 +516,7 @@ pub struct ChunkIter<'self, T> {
476516
}
477517

478518
impl<'self, T> Iterator<&'self [T]> for ChunkIter<'self, T> {
519+
#[inline]
479520
fn next(&mut self) -> Option<&'self [T]> {
480521
if self.v.len() == 0 {
481522
None
@@ -487,9 +528,21 @@ impl<'self, T> Iterator<&'self [T]> for ChunkIter<'self, T> {
487528
Some(fst)
488529
}
489530
}
531+
532+
#[inline]
533+
fn size_hint(&self) -> (uint, Option<uint>) {
534+
if self.v.len() == 0 {
535+
(0, Some(0))
536+
} else {
537+
let (n, rem) = self.v.len().div_rem(&self.size);
538+
let n = if rem > 0 { n+1 } else { n };
539+
(n, Some(n))
540+
}
541+
}
490542
}
491543

492544
impl<'self, T> DoubleEndedIterator<&'self [T]> for ChunkIter<'self, T> {
545+
#[inline]
493546
fn next_back(&mut self) -> Option<&'self [T]> {
494547
if self.v.len() == 0 {
495548
None
@@ -2223,6 +2276,7 @@ impl<'self, T> RandomAccessIterator<&'self T> for VecIterator<'self, T> {
22232276
exact
22242277
}
22252278

2279+
#[inline]
22262280
fn idx(&self, index: uint) -> Option<&'self T> {
22272281
unsafe {
22282282
if index < self.indexable() {
@@ -2268,6 +2322,7 @@ pub struct MoveIterator<T> {
22682322
}
22692323

22702324
impl<T> Iterator<T> for MoveIterator<T> {
2325+
#[inline]
22712326
fn next(&mut self) -> Option<T> {
22722327
// this is peculiar, but is required for safety with respect
22732328
// to dtors. It traverses the first half of the vec, and
@@ -2285,6 +2340,12 @@ impl<T> Iterator<T> for MoveIterator<T> {
22852340

22862341
self.v.pop_opt()
22872342
}
2343+
2344+
#[inline]
2345+
fn size_hint(&self) -> (uint, Option<uint>) {
2346+
let l = self.v.len();
2347+
(l, Some(l))
2348+
}
22882349
}
22892350

22902351
/// An iterator that moves out of a vector in reverse order.
@@ -2294,9 +2355,16 @@ pub struct MoveRevIterator<T> {
22942355
}
22952356

22962357
impl<T> Iterator<T> for MoveRevIterator<T> {
2358+
#[inline]
22972359
fn next(&mut self) -> Option<T> {
22982360
self.v.pop_opt()
22992361
}
2362+
2363+
#[inline]
2364+
fn size_hint(&self) -> (uint, Option<uint>) {
2365+
let l = self.v.len();
2366+
(l, Some(l))
2367+
}
23002368
}
23012369

23022370
impl<A> FromIterator<A> for ~[A] {

0 commit comments

Comments
 (0)