提交 085c4b43 编写于 作者: B bors

Auto merge of #49201 - Phlosioneer:add-trivial-size-hints, r=SimonSapin

Implement some trivial size_hints for various iterators

This also implements ExactSizeIterator where applicable.

Addresses most of the Iterator traits mentioned in #23708.

I intend to do more, but I don't want to make the PR too large.
......@@ -902,6 +902,16 @@ fn next(&mut self) -> Option<Result<char, InvalidSequence>> {
}
})
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (lower, upper) = self.0.size_hint();
// A code point is at most 4 bytes long.
let min_code_points = lower / 4;
(min_code_points, upper)
}
}
#[unstable(feature = "decode_utf8", issue = "33906")]
......
......@@ -901,6 +901,15 @@ fn next(&mut self) -> Option<Self::Item> {
None => None,
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
if self.error.is_some() {
(0, Some(0))
} else {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
}
#[stable(feature = "iter_arith_traits_result", since="1.16.0")]
......
......@@ -1188,6 +1188,16 @@ fn next(&mut self) -> Option<T> {
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
if self.found_none {
(0, Some(0))
} else {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
}
let mut adapter = Adapter { iter: iter.into_iter(), found_none: false };
......
......@@ -31,6 +31,10 @@ fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> {
(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 {
......
......@@ -77,8 +77,18 @@ fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'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 @@ fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'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 @@ fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'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> {}
......@@ -78,4 +78,11 @@ fn next(&mut self) -> Option<(&'a Path, PathKind)> {
}
}
}
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)
}
}
......@@ -347,6 +347,11 @@ fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.base_iterator.size_hint();
(0, upper)
}
}
///////////////////////////////////////////////////////////////////////////
......
......@@ -132,6 +132,11 @@ fn next(&mut self) -> Option<usize> {
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 {
......
......@@ -334,6 +334,11 @@ fn next(&mut self) -> Option<(EdgeIndex, &'g Edge<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 @@ fn next(&mut self) -> Option<NodeIndex> {
}
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
......
......@@ -584,6 +584,13 @@ fn next(&mut self) -> Option<ast::NodeId> {
&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 {
......
......@@ -730,8 +730,15 @@ fn next(&mut self) -> Option<TraitInfo> {
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,
......
......@@ -604,6 +604,11 @@ fn next(&mut self) -> Option<Self::Item> {
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
let lower = self.current_list.len();
(lower, None)
}
}
pub trait AttributesExt {
......
......@@ -272,6 +272,11 @@ fn next(&mut self) -> Option<Self::Item> {
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 @@ fn next(&mut self) -> Option<Self::Item> {
None => None,
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(self.s.len()))
}
}
/// Parse the next substitution from the input string.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册