diff options
| author | Phlosioneer <mattmdrr2@gmail.com> | 2018-03-20 05:33:59 -0400 |
|---|---|---|
| committer | Phlosioneer <mattmdrr2@gmail.com> | 2018-03-20 05:33:59 -0400 |
| commit | 619003d1d414167630331efffe83702f74413be6 (patch) | |
| tree | c986c64f37ab88feda2f7df926261e133d385aad | |
| parent | 6bfa7d02d6713acd15ead20c199b808e85031f9e (diff) | |
| download | rust-619003d1d414167630331efffe83702f74413be6.tar.gz rust-619003d1d414167630331efffe83702f74413be6.zip | |
Implement some trivial size_hints for various iterators
This also implements ExactSizeIterator where applicable. Addresses most of the Iterator traits mentioned in #23708.
| -rw-r--r-- | src/libcore/char.rs | 5 | ||||
| -rw-r--r-- | src/libcore/iter/traits.rs | 4 | ||||
| -rw-r--r-- | src/libcore/option.rs | 5 | ||||
| -rw-r--r-- | src/librustc/hir/pat_util.rs | 4 | ||||
| -rw-r--r-- | src/librustc/mir/traversal.rs | 26 | ||||
| -rw-r--r-- | src/librustc/session/search_paths.rs | 7 | ||||
| -rw-r--r-- | src/librustc/traits/util.rs | 5 | ||||
| -rw-r--r-- | src/librustc_data_structures/bitvec.rs | 5 | ||||
| -rw-r--r-- | src/librustc_data_structures/graph/mod.rs | 13 | ||||
| -rw-r--r-- | src/librustc_driver/pretty.rs | 7 | ||||
| -rw-r--r-- | src/librustc_typeck/check/method/suggest.rs | 7 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax_ext/format_foreign.rs | 9 |
13 files changed, 102 insertions, 0 deletions
diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 1638f9710f5..2f56238a463 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -902,6 +902,11 @@ impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> { } }) } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.0.size_hint() + } } #[unstable(feature = "decode_utf8", issue = "33906")] diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index 0267fcd3754..5e4622f804a 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -901,6 +901,10 @@ impl<I, T, E> Iterator for ResultShunt<I, E> None => None, } } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } } #[stable(feature = "iter_arith_traits_result", since="1.16.0")] diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 570f745f833..1ca69f3f503 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -1188,6 +1188,11 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> { None => None, } } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } } let mut adapter = Adapter { iter: iter.into_iter(), found_none: false }; diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 2bec224362e..1f00a3ab1f5 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -31,6 +31,10 @@ impl<I> Iterator for EnumerateAndAdjust<I> where I: Iterator { (if i < self.gap_pos { i } else { i + self.gap_len }, elem) }) } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.enumerate.size_hint() + } } pub trait EnumerateAndAdjustIterator { diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index 74c3408c4c2..666ca5eabe8 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -77,8 +77,18 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { None } + + fn size_hint(&self) -> (usize, Option<usize>) { + // All the blocks, minus the number of blocks we've visited. + let remaining = self.mir.basic_blocks().len() - self.visited.count(); + + // We will visit all remaining blocks exactly once. + (remaining, Some(remaining)) + } } +impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {} + /// Postorder traversal of a graph. /// /// Postorder traversal is when each node is visited after all of it's @@ -210,8 +220,18 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { next.map(|(bb, _)| (bb, &self.mir[bb])) } + + fn size_hint(&self) -> (usize, Option<usize>) { + // All the blocks, minus the number of blocks we've visited. + let remaining = self.mir.basic_blocks().len() - self.visited.count(); + + // We will visit all remaining blocks exactly once. + (remaining, Some(remaining)) + } } +impl<'a, 'tcx> ExactSizeIterator for Postorder<'a, 'tcx> {} + /// Reverse postorder traversal of a graph /// /// Reverse postorder is the reverse order of a postorder traversal. @@ -276,4 +296,10 @@ impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> { self.blocks.get(self.idx).map(|&bb| (bb, &self.mir[bb])) } + + fn size_hint(&self) -> (usize, Option<usize>) { + (self.idx, Some(self.idx)) + } } + +impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {} diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 5bbc6841693..d2dca9f6084 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -78,4 +78,11 @@ impl<'a> Iterator for Iter<'a> { } } } + + fn size_hint(&self) -> (usize, Option<usize>) { + // This iterator will never return more elements than the base iterator; + // but it can ignore all the remaining elements. + let (_, upper) = self.iter.size_hint(); + (0, upper) + } } diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 8f7a2405747..9e38911f53c 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -347,6 +347,11 @@ impl<'tcx,I:Iterator<Item=ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> { } } } + + fn size_hint(&self) -> (usize, Option<usize>) { + let (_, upper) = self.base_iterator.size_hint(); + (0, upper) + } } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_data_structures/bitvec.rs b/src/librustc_data_structures/bitvec.rs index 54565afa4c6..28e3180063c 100644 --- a/src/librustc_data_structures/bitvec.rs +++ b/src/librustc_data_structures/bitvec.rs @@ -132,6 +132,11 @@ impl<'a> Iterator for BitVectorIter<'a> { self.idx += offset + 1; return Some(self.idx - 1); } + + fn size_hint(&self) -> (usize, Option<usize>) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } } impl FromIterator<bool> for BitVector { diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 1945b82c031..e2b393071ff 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -334,6 +334,11 @@ impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> { self.next = edge.next_edge[self.direction.repr]; Some((edge_index, edge)) } + + fn size_hint(&self) -> (usize, Option<usize>) { + // At most, all the edges in the graph. + (0, Some(self.graph.len_edges())) + } } pub struct DepthFirstTraversal<'g, N, E> @@ -383,8 +388,16 @@ impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> { } next } + + fn size_hint(&self) -> (usize, Option<usize>) { + // We will visit every node in the graph exactly once. + let remaining = self.graph.len_nodes() - self.visited.count(); + (remaining, Some(remaining)) + } } +impl<'g, N: Debug, E: Debug> ExactSizeIterator for DepthFirstTraversal<'g, N, E> {} + impl<E> Edge<E> { pub fn source(&self) -> NodeIndex { self.source diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 4ae6a93d698..c5e7fdb30d3 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -584,6 +584,13 @@ impl<'a, 'hir> Iterator for NodesMatchingUII<'a, 'hir> { &mut NodesMatchingSuffix(ref mut iter) => iter.next(), } } + + fn size_hint(&self) -> (usize, Option<usize>) { + match self { + &NodesMatchingDirect(ref iter) => iter.size_hint(), + &NodesMatchingSuffix(ref iter) => iter.size_hint(), + } + } } impl UserIdentifiedItem { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 61afac97d64..a7536980503 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -718,8 +718,15 @@ impl<'a> Iterator for AllTraits<'a> { TraitInfo::new(*info) }) } + + fn size_hint(&self) -> (usize, Option<usize>) { + let len = self.borrow.as_ref().unwrap().len() - self.idx; + (len, Some(len)) + } } +impl<'a> ExactSizeIterator for AllTraits<'a> {} + struct UsePlacementFinder<'a, 'tcx: 'a, 'gcx: 'tcx> { target_module: ast::NodeId, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 904c24815cb..a2a0e878fd8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -602,6 +602,11 @@ impl<'a> Iterator for ListAttributesIter<'a> { None } + + fn size_hint(&self) -> (usize, Option<usize>) { + let lower = self.current_list.len(); + (lower, None) + } } pub trait AttributesExt { diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs index 0476d7d4fcc..e95c6f2e124 100644 --- a/src/libsyntax_ext/format_foreign.rs +++ b/src/libsyntax_ext/format_foreign.rs @@ -272,6 +272,11 @@ pub mod printf { self.s = tail; Some(sub) } + + fn size_hint(&self) -> (usize, Option<usize>) { + // Substitutions are at least 2 characters long. + (0, Some(self.s.len() / 2)) + } } enum State { @@ -782,6 +787,10 @@ pub mod shell { None => None, } } + + fn size_hint(&self) -> (usize, Option<usize>) { + (0, Some(self.s.len())) + } } /// Parse the next substitution from the input string. |
