Skip to content

Commit 1fe0a8b

Browse files
committed
Implement TrustedLen for Take<Repeat> and Take<RangeFrom>
1 parent 6741e41 commit 1fe0a8b

File tree

3 files changed

+45
-10
lines changed

3 files changed

+45
-10
lines changed

src/libcore/iter/mod.rs

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,16 +2286,7 @@ impl<I> Iterator for Take<I> where I: Iterator{
22862286

22872287
#[inline]
22882288
fn size_hint(&self) -> (usize, Option<usize>) {
2289-
let (lower, upper) = self.iter.size_hint();
2290-
2291-
let lower = cmp::min(lower, self.n);
2292-
2293-
let upper = match upper {
2294-
Some(x) if x < self.n => Some(x),
2295-
_ => Some(self.n)
2296-
};
2297-
2298-
(lower, upper)
2289+
TakeImpl::size_hint(self)
22992290
}
23002291

23012292
#[inline]
@@ -2316,12 +2307,50 @@ impl<I> Iterator for Take<I> where I: Iterator{
23162307
}
23172308
}
23182309

2310+
trait TakeImpl {
2311+
fn size_hint(&self) -> (usize, Option<usize>);
2312+
}
2313+
2314+
impl<I: Iterator> TakeImpl for Take<I> {
2315+
#[inline]
2316+
default fn size_hint(&self) -> (usize, Option<usize>) {
2317+
let (lower, upper) = self.iter.size_hint();
2318+
2319+
let lower = cmp::min(lower, self.n);
2320+
2321+
let upper = match upper {
2322+
Some(x) if x < self.n => Some(x),
2323+
_ => Some(self.n)
2324+
};
2325+
2326+
(lower, upper)
2327+
}
2328+
}
2329+
2330+
impl<I: TrustedLen> TakeImpl for Take<I> {
2331+
#[inline]
2332+
fn size_hint(&self) -> (usize, Option<usize>) {
2333+
let (lower, upper) = self.iter.size_hint();
2334+
match upper {
2335+
None => (self.n, Some(self.n)),
2336+
Some(x) => {
2337+
debug_assert_eq!(x, lower);
2338+
let count = cmp::min(lower, self.n);
2339+
(count, Some(count))
2340+
}
2341+
}
2342+
}
2343+
}
2344+
23192345
#[stable(feature = "rust1", since = "1.0.0")]
23202346
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
23212347

23222348
#[unstable(feature = "fused", issue = "35602")]
23232349
impl<I> FusedIterator for Take<I> where I: FusedIterator {}
23242350

2351+
#[unstable(feature = "trusted_len", issue = "37572")]
2352+
unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
2353+
23252354
/// An iterator to maintain state while iterating another iterator.
23262355
///
23272356
/// This `struct` is created by the [`scan`] method on [`Iterator`]. See its

src/libcore/iter/range.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ impl<A: Step> Iterator for ops::RangeFrom<A> {
325325
#[unstable(feature = "fused", issue = "35602")]
326326
impl<A: Step> FusedIterator for ops::RangeFrom<A> {}
327327

328+
#[unstable(feature = "trusted_len", issue = "37572")]
329+
unsafe impl<A: Step> TrustedLen for ops::RangeFrom<A> {}
330+
328331
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
329332
impl<A: Step> Iterator for ops::RangeInclusive<A> {
330333
type Item = A;

src/libcore/iter/sources.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ impl<A: Clone> DoubleEndedIterator for Repeat<A> {
4444
#[unstable(feature = "fused", issue = "35602")]
4545
impl<A: Clone> FusedIterator for Repeat<A> {}
4646

47+
#[unstable(feature = "trusted_len", issue = "37572")]
48+
unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
49+
4750
/// Creates a new iterator that endlessly repeats a single element.
4851
///
4952
/// The `repeat()` function repeats a single value over and over and over and

0 commit comments

Comments
 (0)