diff options
Diffstat (limited to 'ecs/src/util.rs')
-rw-r--r-- | ecs/src/util.rs | 132 |
1 files changed, 131 insertions, 1 deletions
diff --git a/ecs/src/util.rs b/ecs/src/util.rs index 71021cd..fbd33fa 100644 --- a/ecs/src/util.rs +++ b/ecs/src/util.rs @@ -1,8 +1,138 @@ use std::hash::Hash; -use std::ops::BitAnd; +use std::mem::transmute; +use std::ops::{BitAnd, Deref}; use hashbrown::HashMap; +pub trait VecExt<Item> +{ + fn insert_at_partition_point_by_key<Key>( + &mut self, + item: Item, + func: impl FnMut(&Item) -> Key, + ) where + Key: Ord; +} + +impl<Item> VecExt<Item> for Vec<Item> +{ + fn insert_at_partition_point_by_key<Key>( + &mut self, + item: Item, + mut func: impl FnMut(&Item) -> Key, + ) where + Key: Ord, + { + let key = func(&item); + + let insert_index = self.partition_point(|other_item| func(other_item) <= key); + + self.insert(insert_index, item); + } +} + +pub trait StreamingIterator +{ + type Item<'a> + where + Self: 'a; + + fn streaming_next(&mut self) -> Option<Self::Item<'_>>; + + fn streaming_map<NewItem, Func>(self, func: Func) -> StreamingMap<Self, Func> + where + Self: Sized, + Func: FnMut(Self::Item<'_>) -> NewItem, + { + StreamingMap { iter: self, func } + } + + fn streaming_find<'this, Predicate>( + &'this mut self, + mut predicate: Predicate, + ) -> Option<Self::Item<'this>> + where + Self: Sized, + Predicate: FnMut(&Self::Item<'this>) -> bool, + { + while let Some(item) = + unsafe { transmute::<_, Option<Self::Item<'_>>>(self.streaming_next()) } + { + if predicate(&item) { + return Some(item); + } + } + + None + } +} + +pub struct StreamingMap<Iter, Func> +{ + iter: Iter, + func: Func, +} + +impl<Iter, Func, Item> StreamingIterator for StreamingMap<Iter, Func> +where + Iter: StreamingIterator, + Func: FnMut(Iter::Item<'_>) -> Item, +{ + type Item<'a> + = Item + where + Iter: 'a, + Func: 'a; + + fn streaming_next(&mut self) -> Option<Self::Item<'_>> + { + Some((self.func)(self.iter.streaming_next()?)) + } +} + +#[derive(Debug)] +pub enum BorrowedOrOwned<'a, Value> +{ + Borrowned(&'a Value), + Owned(Value), +} + +impl<'a, Value> Deref for BorrowedOrOwned<'a, Value> +{ + type Target = Value; + + fn deref(&self) -> &Self::Target + { + match self { + Self::Borrowned(value) => value, + Self::Owned(value) => value, + } + } +} + +#[derive(Debug, Clone)] +pub enum Either<A, B> +{ + A(A), + B(B), +} + +impl<A, B> Iterator for Either<A, B> +where + A: Iterator, + B: Iterator<Item = A::Item>, +{ + type Item = A::Item; + + fn next(&mut self) -> Option<Self::Item> + { + match self { + Self::A(a) => a.next(), + Self::B(b) => b.next(), + } + } +} + pub trait HashMapExt<Key, Value> { /// Returns true if the keys are a subset of another [`HashMap`]'s keys, i.e., `other` |