Skip to content

Commit

Permalink
Implement FusedIterator for eligible Iterator types (bevyengine#4942)
Browse files Browse the repository at this point in the history
# Objective
Most of our `Iterator` impls satisfy the requirements of `std::iter::FusedIterator`, which has internal specialization that optimizes `Interator::fuse`. The std lib iterator combinators do have a few that rely on `fuse`, so this could optimize those use cases. I don't think we're using any of them in the engine itself, but beyond a light increase in compile time, it doesn't hurt to implement the trait.

## Solution
Implement the trait for all eligible iterators in first party crates. Also add a missing `ExactSizeIterator` on an iterator that could use it.
  • Loading branch information
james7132 authored and ItsDoot committed Feb 1, 2023
1 parent 3f81643 commit 5abbfcc
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 4 deletions.
1 change: 1 addition & 0 deletions crates/bevy_ecs/src/entity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ impl<'a> Iterator for ReserveEntitiesIterator<'a> {
}

impl<'a> core::iter::ExactSizeIterator for ReserveEntitiesIterator<'a> {}
impl<'a> core::iter::FusedIterator for ReserveEntitiesIterator<'a> {}

#[derive(Debug, Default)]
pub struct Entities {
Expand Down
17 changes: 16 additions & 1 deletion crates/bevy_ecs/src/query/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
query::{Fetch, QueryState, WorldQuery},
storage::{TableId, Tables},
};
use std::{borrow::Borrow, marker::PhantomData, mem::MaybeUninit};
use std::{borrow::Borrow, iter::FusedIterator, marker::PhantomData, mem::MaybeUninit};

use super::{QueryFetch, QueryItem, ReadOnlyFetch};

Expand Down Expand Up @@ -72,6 +72,12 @@ where
}
}

// This is correct as [`QueryIter`] always returns `None` once exhausted.
impl<'w, 's, Q: WorldQuery, QF, F: WorldQuery> FusedIterator for QueryIter<'w, 's, Q, QF, F> where
QF: Fetch<'w, State = Q::State>
{
}

/// An [`Iterator`] over query results of a [`Query`](crate::system::Query).
///
/// This struct is created by the [`Query::iter_many`](crate::system::Query::iter_many) method.
Expand Down Expand Up @@ -359,6 +365,15 @@ where
}
}

// This is correct as [`QueryCombinationIter`] always returns `None` once exhausted.
impl<'w, 's, Q: WorldQuery, F: WorldQuery, const K: usize> FusedIterator
for QueryCombinationIter<'w, 's, Q, F, K>
where
QueryFetch<'w, Q>: Clone + ReadOnlyFetch,
QueryFetch<'w, F>: Clone + ReadOnlyFetch,
{
}

struct QueryIterationCursor<'w, 's, Q: WorldQuery, QF: Fetch<'w, State = Q::State>, F: WorldQuery> {
table_id_iter: std::slice::Iter<'s, TableId>,
archetype_id_iter: std::slice::Iter<'s, ArchetypeId>,
Expand Down
8 changes: 8 additions & 0 deletions crates/bevy_ecs/src/world/spawn_batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
entity::Entity,
world::World,
};
use std::iter::FusedIterator;

pub struct SpawnBatchIter<'w, I>
where
Expand Down Expand Up @@ -84,3 +85,10 @@ where
self.inner.len()
}
}

impl<I, T> FusedIterator for SpawnBatchIter<'_, I>
where
I: FusedIterator<Item = T>,
T: Bundle,
{
}
2 changes: 1 addition & 1 deletion crates/bevy_reflect/src/array.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{serde::Serializable, Reflect, ReflectMut, ReflectRef};
use std::fmt::Debug;
use std::{
any::Any,
fmt::Debug,
hash::{Hash, Hasher},
};

Expand Down
12 changes: 11 additions & 1 deletion crates/bevy_render/src/mesh/mesh/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use bevy_ecs::system::{lifetimeless::SRes, SystemParamItem};
use bevy_math::*;
use bevy_reflect::TypeUuid;
use bevy_utils::Hashed;
use std::{collections::BTreeMap, hash::Hash};
use std::{collections::BTreeMap, hash::Hash, iter::FusedIterator};
use thiserror::Error;
use wgpu::{
util::BufferInitDescriptor, BufferUsages, IndexFormat, VertexAttribute, VertexFormat,
Expand Down Expand Up @@ -749,8 +749,18 @@ impl Iterator for IndicesIter<'_> {
IndicesIter::U32(iter) => iter.next().map(|val| *val as usize),
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
match self {
IndicesIter::U16(iter) => iter.size_hint(),
IndicesIter::U32(iter) => iter.size_hint(),
}
}
}

impl<'a> ExactSizeIterator for IndicesIter<'a> {}
impl<'a> FusedIterator for IndicesIter<'a> {}

impl From<&Indices> for IndexFormat {
fn from(indices: &Indices) -> Self {
match indices {
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_render/src/render_resource/pipeline_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use bevy_asset::{AssetEvent, Assets, Handle};
use bevy_ecs::event::EventReader;
use bevy_ecs::system::{Res, ResMut};
use bevy_utils::{default, tracing::error, Entry, HashMap, HashSet};
use std::{hash::Hash, mem, ops::Deref, sync::Arc};
use std::{hash::Hash, iter::FusedIterator, mem, ops::Deref, sync::Arc};
use thiserror::Error;
use wgpu::{PipelineLayoutDescriptor, ShaderModule, VertexBufferLayout as RawVertexBufferLayout};

Expand Down Expand Up @@ -672,3 +672,5 @@ impl<'a> Iterator for ErrorSources<'a> {
current
}
}

impl<'a> FusedIterator for ErrorSources<'a> {}

0 comments on commit 5abbfcc

Please sign in to comment.