|
1 | 1 | use crate::fmt;
|
2 |
| -use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map}; |
| 2 | +use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen}; |
3 | 3 | use crate::ops::Try;
|
4 | 4 |
|
5 | 5 | /// An iterator that maps each element to an iterator, and yields the elements
|
@@ -114,6 +114,14 @@ where
|
114 | 114 | {
|
115 | 115 | }
|
116 | 116 |
|
| 117 | +#[unstable(feature = "trusted_len", issue = "37572")] |
| 118 | +unsafe impl<T, I, F, const N: usize> TrustedLen for FlatMap<I, [T; N], F> |
| 119 | +where |
| 120 | + I: TrustedLen, |
| 121 | + F: FnMut(I::Item) -> [T; N], |
| 122 | +{ |
| 123 | +} |
| 124 | + |
117 | 125 | /// An iterator that flattens one level of nesting in an iterator of things
|
118 | 126 | /// that can be turned into iterators.
|
119 | 127 | ///
|
@@ -230,6 +238,12 @@ where
|
230 | 238 | {
|
231 | 239 | }
|
232 | 240 |
|
| 241 | +#[unstable(feature = "trusted_len", issue = "37572")] |
| 242 | +unsafe impl<T, I, const N: usize> TrustedLen for Flatten<I> where |
| 243 | + I: Iterator<Item = [T; N]> + TrustedLen |
| 244 | +{ |
| 245 | +} |
| 246 | + |
233 | 247 | /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
|
234 | 248 | /// this type.
|
235 | 249 | #[derive(Clone, Debug)]
|
@@ -282,6 +296,21 @@ where
|
282 | 296 | let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
|
283 | 297 | let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
|
284 | 298 | let lo = flo.saturating_add(blo);
|
| 299 | + |
| 300 | + if let Some(fixed_size) = <<I as Iterator>::Item as ConstSizeIterable>::size() { |
| 301 | + let (lower, upper) = self.iter.size_hint(); |
| 302 | + |
| 303 | + let lower = lower.saturating_mul(fixed_size).saturating_add(lo); |
| 304 | + let upper = upper.and_then(|i| i.checked_mul(fixed_size)); |
| 305 | + let upper = fhi |
| 306 | + .zip_with(bhi, usize::checked_add) |
| 307 | + .flatten() |
| 308 | + .zip_with(upper, usize::checked_add) |
| 309 | + .flatten(); |
| 310 | + |
| 311 | + return (lower, upper); |
| 312 | + } |
| 313 | + |
285 | 314 | match (self.iter.size_hint(), fhi, bhi) {
|
286 | 315 | ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
|
287 | 316 | _ => (lo, None),
|
@@ -444,3 +473,21 @@ where
|
444 | 473 | init
|
445 | 474 | }
|
446 | 475 | }
|
| 476 | + |
| 477 | +trait ConstSizeIterable { |
| 478 | + fn size() -> Option<usize>; |
| 479 | +} |
| 480 | + |
| 481 | +impl<T> ConstSizeIterable for T { |
| 482 | + #[inline] |
| 483 | + default fn size() -> Option<usize> { |
| 484 | + None |
| 485 | + } |
| 486 | +} |
| 487 | + |
| 488 | +impl<T, const N: usize> ConstSizeIterable for [T; N] { |
| 489 | + #[inline] |
| 490 | + fn size() -> Option<usize> { |
| 491 | + Some(N) |
| 492 | + } |
| 493 | +} |
0 commit comments