diff --git a/crates/bevy_ecs/src/entity/entity_set.rs b/crates/bevy_ecs/src/entity/entity_set.rs index 6b69897806071..f75e59113932e 100644 --- a/crates/bevy_ecs/src/entity/entity_set.rs +++ b/crates/bevy_ecs/src/entity/entity_set.rs @@ -13,7 +13,7 @@ use core::{ option, result, }; -use super::Entity; +use super::{Entity, UniqueEntitySlice}; use bevy_platform_support::sync::Arc; @@ -350,6 +350,7 @@ impl UniqueEntityIter { Self { iter } } } + impl> UniqueEntityIter { /// Constructs a [`UniqueEntityIter`] from an iterator unsafely. /// @@ -359,6 +360,26 @@ impl> UniqueEntityIter { pub unsafe fn from_iterator_unchecked(iter: I) -> Self { Self { iter } } + + /// Returns the inner `I`. + pub fn into_inner(self) -> I { + self.iter + } + + /// Returns a reference to the inner `I`. + pub fn as_inner(&self) -> &I { + &self.iter + } + + /// Returns a mutable reference to the inner `I`. + /// + /// # Safety + /// + /// `self` must always contain an iterator that yields unique elements, + /// even while this reference is live. + pub unsafe fn as_mut_inner(&mut self) -> &mut I { + &mut self.iter + } } impl> Iterator for UniqueEntityIter { @@ -394,6 +415,24 @@ impl + AsRef<[T]>> AsRef<[T]> for Uniq } } +impl + AsRef<[T]>> + AsRef> for UniqueEntityIter +{ + fn as_ref(&self) -> &UniqueEntitySlice { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.iter.as_ref()) } + } +} + +impl + AsMut<[T]>> + AsMut> for UniqueEntityIter +{ + fn as_mut(&mut self) -> &mut UniqueEntitySlice { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.iter.as_mut()) } + } +} + // Default does not guarantee uniqueness, meaning `I` needs to be EntitySetIterator. impl Default for UniqueEntityIter { fn default() -> Self { diff --git a/crates/bevy_ecs/src/entity/mod.rs b/crates/bevy_ecs/src/entity/mod.rs index 8be4df3643149..3f3ef9370b5b7 100644 --- a/crates/bevy_ecs/src/entity/mod.rs +++ b/crates/bevy_ecs/src/entity/mod.rs @@ -66,6 +66,10 @@ mod index_set; pub use index_map::EntityIndexMap; pub use index_set::EntityIndexSet; +mod unique_slice; + +pub use unique_slice::*; + use crate::{ archetype::{ArchetypeId, ArchetypeRow}, identifier::{ diff --git a/crates/bevy_ecs/src/entity/unique_slice.rs b/crates/bevy_ecs/src/entity/unique_slice.rs new file mode 100644 index 0000000000000..d9f01277dc10f --- /dev/null +++ b/crates/bevy_ecs/src/entity/unique_slice.rs @@ -0,0 +1,975 @@ +use core::{ + borrow::Borrow, + cmp::Ordering, + fmt::Debug, + ops::{ + Bound, Deref, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, + RangeToInclusive, + }, + ptr, + slice::{self, SliceIndex}, +}; + +use alloc::{ + borrow::{Cow, ToOwned}, + boxed::Box, + collections::VecDeque, + rc::Rc, + sync::Arc, + vec::Vec, +}; + +use super::{ + unique_vec, EntitySet, EntitySetIterator, FromEntitySetIterator, TrustedEntityBorrow, + UniqueEntityIter, UniqueEntityVec, +}; + +/// A slice that contains only unique entities. +/// +/// It can be obtained by slicing [`UniqueEntityVec`]. +#[repr(transparent)] +#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct UniqueEntitySlice([T]); + +impl UniqueEntitySlice { + /// Constructs a `UniqueEntitySlice` from a [`&[T]`] unsafely. + /// + /// # Safety + /// + /// `slice` must contain only unique elements. + pub const unsafe fn from_slice_unchecked(slice: &[T]) -> &Self { + // SAFETY: UniqueEntitySlice is a transparent wrapper around [T]. + unsafe { &*(ptr::from_ref(slice) as *const Self) } + } + + /// Constructs a `UniqueEntitySlice` from a [`&mut [T]`] unsafely. + /// + /// # Safety + /// + /// `slice` must contain only unique elements. + pub const unsafe fn from_slice_unchecked_mut(slice: &mut [T]) -> &mut Self { + // SAFETY: UniqueEntitySlice is a transparent wrapper around [T]. + unsafe { &mut *(ptr::from_mut(slice) as *mut Self) } + } + + /// Casts to `self` to a standard slice. + pub const fn as_inner(&self) -> &[T] { + &self.0 + } + + /// Constructs a `UniqueEntitySlice` from a [`Box<[T]>`] unsafely. + /// + /// # Safety + /// + /// `slice` must contain only unique elements. + pub unsafe fn from_boxed_slice_unchecked(slice: Box<[T]>) -> Box { + // SAFETY: UniqueEntitySlice is a transparent wrapper around [T]. + unsafe { Box::from_raw(Box::into_raw(slice) as *mut Self) } + } + + /// Casts `self` to the inner slice. + pub fn into_boxed_inner(self: Box) -> Box<[T]> { + // SAFETY: UniqueEntitySlice is a transparent wrapper around [T]. + unsafe { Box::from_raw(Box::into_raw(self) as *mut [T]) } + } + + /// Constructs a `UniqueEntitySlice` from a [`Arc<[T]>`] unsafely. + /// + /// # Safety + /// + /// `slice` must contain only unique elements. + pub unsafe fn from_arc_slice_unchecked(slice: Arc<[T]>) -> Arc { + // SAFETY: UniqueEntitySlice is a transparent wrapper around [T]. + unsafe { Arc::from_raw(Arc::into_raw(slice) as *mut Self) } + } + + /// Casts `self` to the inner slice. + pub fn into_arc_inner(self: Arc) -> Arc<[T]> { + // SAFETY: UniqueEntitySlice is a transparent wrapper around [T]. + unsafe { Arc::from_raw(Arc::into_raw(self) as *mut [T]) } + } + + // Constructs a `UniqueEntitySlice` from a [`Rc<[T]>`] unsafely. + /// + /// # Safety + /// + /// `slice` must contain only unique elements. + pub unsafe fn from_rc_slice_unchecked(slice: Rc<[T]>) -> Rc { + // SAFETY: UniqueEntitySlice is a transparent wrapper around [T]. + unsafe { Rc::from_raw(Rc::into_raw(slice) as *mut Self) } + } + + /// Casts `self` to the inner slice. + pub fn into_rc_inner(self: Rc) -> Rc<[T]> { + // SAFETY: UniqueEntitySlice is a transparent wrapper around [T]. + unsafe { Rc::from_raw(Rc::into_raw(self) as *mut [T]) } + } + + /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty. + /// + /// Equivalent to [`[T]::split_first`](slice::split_first). + pub const fn split_first(&self) -> Option<(&T, &Self)> { + let Some((first, rest)) = self.0.split_first() else { + return None; + }; + // SAFETY: All elements in the original slice are unique. + Some((first, unsafe { Self::from_slice_unchecked(rest) })) + } + + /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty. + /// + /// Equivalent to [`[T]::split_last`](slice::split_last). + pub const fn split_last(&self) -> Option<(&T, &Self)> { + let Some((last, rest)) = self.0.split_last() else { + return None; + }; + // SAFETY: All elements in the original slice are unique. + Some((last, unsafe { Self::from_slice_unchecked(rest) })) + } + + /// Returns a reference to a subslice. + /// + /// Equivalent to the range functionality of [`[T]::get`]. + /// + /// Note that only the inner [`[T]::get`] supports indexing with a [`usize`]. + /// + /// [`[T]::get`]: `slice::get` + pub fn get(&self, index: I) -> Option<&Self> + where + Self: Index, + I: SliceIndex<[T], Output = [T]>, + { + self.0.get(index).map(|slice| + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked(slice) }) + } + + /// Returns a mutable reference to a subslice. + /// + /// Equivalent to the range functionality of [`[T]::get_mut`]. + /// + /// Note that `UniqueEntitySlice::get_mut` cannot be called with a [`usize`]. + /// + /// [`[T]::get_mut`]: `slice::get_mut`s + pub fn get_mut(&mut self, index: I) -> Option<&mut Self> + where + Self: Index, + I: SliceIndex<[T], Output = [T]>, + { + self.0.get_mut(index).map(|slice| + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked_mut(slice) }) + } + + /// Returns a reference to a subslice, without doing bounds checking. + /// + /// Equivalent to the range functionality of [`[T]::get_unchecked`]. + /// + /// Note that only the inner [`[T]::get_unchecked`] supports indexing with a [`usize`]. + /// + /// # Safety + /// + /// `index` must be safe to use with [`[T]::get_unchecked`] + /// + /// [`[T]::get_unchecked`]: `slice::get_unchecked` + pub unsafe fn get_unchecked(&self, index: I) -> &Self + where + Self: Index, + I: SliceIndex<[T], Output = [T]>, + { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked(self.0.get_unchecked(index)) } + } + /// Returns a mutable reference to a subslice, without doing bounds checking. + /// + /// Equivalent to the range functionality of [`[T]::get_unchecked_mut`]. + /// + /// Note that `UniqueEntitySlice::get_unchecked_mut` cannot be called with an index. + /// + /// # Safety + /// + /// `index` must be safe to use with [`[T]::get_unchecked_mut`] + /// + /// [`[T]::get_unchecked_mut`]: `slice::get_unchecked_mut` + pub unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut Self + where + Self: Index, + I: SliceIndex<[T], Output = [T]>, + { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked_mut(self.0.get_unchecked_mut(index)) } + } + + /// Returns an unsafe mutable pointer to the slice's buffer. + pub const fn as_mut_ptr(&mut self) -> *mut T { + self.0.as_mut_ptr() + } + + /// Returns the two unsafe mutable pointers spanning the slice. + pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> { + self.0.as_mut_ptr_range() + } + + /// Swaps two elements in the slice. + pub fn swap(&mut self, a: usize, b: usize) { + self.0.swap(a, b); + } + + /// Reverses the order of elements in the slice, in place. + pub fn reverse(&mut self) { + self.0.reverse(); + } + + /// Returns an iterator over the slice. + pub fn iter(&self) -> Iter<'_, T> { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntityIter::from_iterator_unchecked(self.0.iter()) } + } + + /// Divides one slice into two at an index. + /// + /// Equivalent to [`[T]::split_at`](slice::split_at) + pub const fn split_at(&self, mid: usize) -> (&Self, &Self) { + let (left, right) = self.0.split_at(mid); + // SAFETY: All elements in the original slice are unique. + unsafe { + ( + Self::from_slice_unchecked(left), + Self::from_slice_unchecked(right), + ) + } + } + + /// Divides one mutable slice into two at an index. + /// + /// Equivalent to [`[T]::split_at_mut`](slice::split_at_mut) + pub const fn split_at_mut(&mut self, mid: usize) -> (&mut Self, &mut Self) { + let (left, right) = self.0.split_at_mut(mid); + // SAFETY: All elements in the original slice are unique. + unsafe { + ( + Self::from_slice_unchecked_mut(left), + Self::from_slice_unchecked_mut(right), + ) + } + } + + /// Divides one slice into two at an index, without doing bounds checking. + /// + /// Equivalent to [`[T]::split_at_unchecked`](slice::split_at_unchecked) + /// + /// # Safety + /// + /// `mid` must be safe to use in [`[T]::split_at_unchecked`]. + /// + /// [`[T]::split_at_unchecked`]: `slice::split_at_unchecked` + pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&Self, &Self) { + // SAFETY: The safety contract is upheld by the caller. + let (left, right) = unsafe { self.0.split_at_unchecked(mid) }; + // SAFETY: All elements in the original slice are unique. + unsafe { + ( + Self::from_slice_unchecked(left), + Self::from_slice_unchecked(right), + ) + } + } + + /// Divides one mutable slice into two at an index, without doing bounds checking. + /// + /// Equivalent to [`[T]::split_at_mut_unchecked`](slice::split_at_mut_unchecked). + /// + /// # Safety + /// + /// `mid` must be safe to use in [`[T]::split_at_mut_unchecked`]. + /// + /// [`[T]::split_at_mut_unchecked`]: `slice::split_at_mut_unchecked` + pub const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut Self, &mut Self) { + // SAFETY: The safety contract is upheld by the caller. + let (left, right) = unsafe { self.0.split_at_mut_unchecked(mid) }; + // SAFETY: All elements in the original slice are unique. + unsafe { + ( + Self::from_slice_unchecked_mut(left), + Self::from_slice_unchecked_mut(right), + ) + } + } + + /// Divides one slice into two at an index, returning `None` if the slice is + /// too short. + /// + /// Equivalent to [`[T]::split_at_checked`](slice::split_at_checked). + pub const fn split_at_checked(&self, mid: usize) -> Option<(&Self, &Self)> { + let Some((left, right)) = self.0.split_at_checked(mid) else { + return None; + }; + // SAFETY: All elements in the original slice are unique. + unsafe { + Some(( + Self::from_slice_unchecked(left), + Self::from_slice_unchecked(right), + )) + } + } + + /// Divides one mutable slice into two at an index, returning `None` if the + /// slice is too short. + /// + /// Equivalent to [`[T]::split_at_mut_checked`](slice::split_at_mut_checked). + pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut Self, &mut Self)> { + let Some((left, right)) = self.0.split_at_mut_checked(mid) else { + return None; + }; + // SAFETY: All elements in the original slice are unique. + unsafe { + Some(( + Self::from_slice_unchecked_mut(left), + Self::from_slice_unchecked_mut(right), + )) + } + } + + /// Sorts the slice **without** preserving the initial order of equal elements. + /// + /// Equivalent to [`[T]::sort_unstable`](slice::sort_unstable). + pub fn sort_unstable(&mut self) + where + T: Ord, + { + self.0.sort_unstable(); + } + + /// Sorts the slice with a comparison function, **without** preserving the initial order of + /// equal elements. + /// + /// Equivalent to [`[T]::sort_unstable_by`](slice::sort_unstable_by). + pub fn sort_unstable_by(&mut self, compare: F) + where + F: FnMut(&T, &T) -> Ordering, + { + self.0.sort_unstable_by(compare); + } + + /// Sorts the slice with a key extraction function, **without** preserving the initial order of + /// equal elements. + /// + /// Equivalent to [`[T]::sort_unstable_by_key`](slice::sort_unstable_by_key). + pub fn sort_unstable_by_key(&mut self, f: F) + where + F: FnMut(&T) -> K, + K: Ord, + { + self.0.sort_unstable_by_key(f); + } + + /// Rotates the slice in-place such that the first `mid` elements of the + /// slice move to the end while the last `self.len() - mid` elements move to + /// the front. + /// + /// Equivalent to [`[T]::rotate_left`](slice::rotate_left). + pub fn rotate_left(&mut self, mid: usize) { + self.0.rotate_left(mid); + } + + /// Rotates the slice in-place such that the first `self.len() - k` + /// elements of the slice move to the end while the last `k` elements move + /// to the front. + /// + /// Equivalent to [`[T]::rotate_right`](slice::rotate_right). + pub fn rotate_right(&mut self, mid: usize) { + self.0.rotate_right(mid); + } + + /// Sorts the slice, preserving initial order of equal elements. + /// + /// Equivalent to [`[T]::sort`](slice::sort()). + pub fn sort(&mut self) + where + T: Ord, + { + self.0.sort(); + } + + /// Sorts the slice with a comparison function, preserving initial order of equal elements. + /// + /// Equivalent to [`[T]::sort_by`](slice::sort_by). + pub fn sort_by(&mut self, compare: F) + where + F: FnMut(&T, &T) -> Ordering, + { + self.0.sort_by(compare); + } + + /// Sorts the slice with a key extraction function, preserving initial order of equal elements. + /// + /// Equivalent to [`[T]::sort_by_key`](slice::sort_by_key). + pub fn sort_by_key(&mut self, f: F) + where + F: FnMut(&T) -> K, + K: Ord, + { + self.0.sort_by_key(f); + } + + // Sorts the slice with a key extraction function, preserving initial order of equal elements. + /// + /// Equivalent to [`[T]::sort_by_cached_key`](slice::sort_by_cached_key). + pub fn sort_by_cached_key(&mut self, f: F) + where + F: FnMut(&T) -> K, + K: Ord, + { + self.0.sort_by_cached_key(f); + } + + /// Copies self into a new `UniqueEntityVec`. + pub fn to_vec(&self) -> UniqueEntityVec + where + T: Clone, + { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntityVec::from_vec_unchecked(self.0.to_vec()) } + } + + /// Converts `self` into a vector without clones or allocation. + /// + /// Equivalent to [`[T]::into_vec`](slice::into_vec). + pub fn into_vec(self: Box) -> UniqueEntityVec { + // SAFETY: + // This matches the implementation of `slice::into_vec`. + // All elements in the original slice are unique. + unsafe { + let len = self.len(); + let vec = Vec::from_raw_parts(Box::into_raw(self).cast::(), len, len); + UniqueEntityVec::from_vec_unchecked(vec) + } + } +} + +/// Converts a reference to T into a slice of length 1 (without copying). +pub const fn from_ref(s: &T) -> &UniqueEntitySlice { + // SAFETY: A slice with a length of 1 is always unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(slice::from_ref(s)) } +} + +/// Converts a reference to T into a slice of length 1 (without copying). +pub const fn from_mut(s: &mut T) -> &mut UniqueEntitySlice { + // SAFETY: A slice with a length of 1 is always unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(slice::from_mut(s)) } +} + +/// Forms a slice from a pointer and a length. +/// +/// Equivalent to [`slice::from_raw_parts`]. +/// +/// # Safety +/// +/// [`slice::from_raw_parts`] must be safe to call with `data` and `len`. +/// Additionally, all elements in the resulting slice must be unique. +pub const unsafe fn from_raw_parts<'a, T: TrustedEntityBorrow>( + data: *const T, + len: usize, +) -> &'a UniqueEntitySlice { + // SAFETY: The safety contract is upheld by the caller. + unsafe { UniqueEntitySlice::from_slice_unchecked(slice::from_raw_parts(data, len)) } +} + +/// Performs the same functionality as [`from_raw_parts`], except that a mutable slice is returned. +/// +/// Equivalent to [`slice::from_raw_parts_mut`]. +/// +/// # Safety +/// +/// [`slice::from_raw_parts_mut`] must be safe to call with `data` and `len`. +/// Additionally, all elements in the resulting slice must be unique. +pub const unsafe fn from_raw_parts_mut<'a, T: TrustedEntityBorrow>( + data: *mut T, + len: usize, +) -> &'a mut UniqueEntitySlice { + // SAFETY: The safety contract is upheld by the caller. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(slice::from_raw_parts_mut(data, len)) } +} + +impl<'a, T: TrustedEntityBorrow> IntoIterator for &'a UniqueEntitySlice { + type Item = &'a T; + + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a, T: TrustedEntityBorrow> IntoIterator for &'a Box> { + type Item = &'a T; + + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl IntoIterator for Box> { + type Item = T; + + type IntoIter = unique_vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.into_vec().into_iter() + } +} + +impl Deref for UniqueEntitySlice { + type Target = [T]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl AsRef<[T]> for UniqueEntitySlice { + fn as_ref(&self) -> &[T] { + self + } +} + +impl AsRef for UniqueEntitySlice { + fn as_ref(&self) -> &Self { + self + } +} + +impl AsMut for UniqueEntitySlice { + fn as_mut(&mut self) -> &mut Self { + self + } +} + +impl Borrow<[T]> for UniqueEntitySlice { + fn borrow(&self) -> &[T] { + self + } +} + +impl Clone for Box> { + fn clone(&self) -> Self { + self.to_vec().into_boxed_slice() + } +} + +impl Default for &UniqueEntitySlice { + fn default() -> Self { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(Default::default()) } + } +} + +impl Default for &mut UniqueEntitySlice { + fn default() -> Self { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(Default::default()) } + } +} + +impl Default for Box> { + fn default() -> Self { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_boxed_slice_unchecked(Default::default()) } + } +} + +impl From<&UniqueEntitySlice> for Box> { + fn from(value: &UniqueEntitySlice) -> Self { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_boxed_slice_unchecked(value.0.into()) } + } +} + +impl From<&UniqueEntitySlice> for Arc> { + fn from(value: &UniqueEntitySlice) -> Self { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_arc_slice_unchecked(value.0.into()) } + } +} + +impl From<&UniqueEntitySlice> for Rc> { + fn from(value: &UniqueEntitySlice) -> Self { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_rc_slice_unchecked(value.0.into()) } + } +} + +impl<'a, T: TrustedEntityBorrow + Clone> From<&'a UniqueEntitySlice> + for Cow<'a, UniqueEntitySlice> +{ + fn from(value: &'a UniqueEntitySlice) -> Self { + Cow::Borrowed(value) + } +} + +impl<'a, T: TrustedEntityBorrow + Clone> From>> + for Box> +{ + fn from(value: Cow<'a, UniqueEntitySlice>) -> Self { + match value { + Cow::Borrowed(slice) => Box::from(slice), + Cow::Owned(slice) => Box::from(slice), + } + } +} + +impl From> for Box> { + fn from(value: UniqueEntityVec) -> Self { + value.into_boxed_slice() + } +} + +impl FromIterator for Box> { + fn from_iter>(iter: I) -> Self { + iter.into_iter() + .collect::>() + .into_boxed_slice() + } +} + +impl FromEntitySetIterator for Box> { + fn from_entity_set_iter>(iter: I) -> Self { + iter.into_iter() + .collect_set::>() + .into_boxed_slice() + } +} + +impl, U: TrustedEntityBorrow> PartialEq> + for &UniqueEntitySlice +{ + fn eq(&self, other: &UniqueEntityVec) -> bool { + self.0.eq(other.as_vec()) + } +} + +impl, U: TrustedEntityBorrow> PartialEq> + for &mut UniqueEntitySlice +{ + fn eq(&self, other: &UniqueEntityVec) -> bool { + self.0.eq(other.as_vec()) + } +} + +impl, U: TrustedEntityBorrow> PartialEq> + for UniqueEntitySlice +{ + fn eq(&self, other: &UniqueEntityVec) -> bool { + self.0.eq(other.as_vec()) + } +} + +impl, U: TrustedEntityBorrow, const N: usize> PartialEq<&UniqueEntitySlice> + for [T; N] +{ + fn eq(&self, other: &&UniqueEntitySlice) -> bool { + self.eq(&other.0) + } +} + +impl + Clone, U: TrustedEntityBorrow> PartialEq<&UniqueEntitySlice> + for Cow<'_, [T]> +{ + fn eq(&self, other: &&UniqueEntitySlice) -> bool { + self.eq(&&other.0) + } +} + +impl + Clone, U: TrustedEntityBorrow> + PartialEq<&UniqueEntitySlice> for Cow<'_, UniqueEntitySlice> +{ + fn eq(&self, other: &&UniqueEntitySlice) -> bool { + self.0.eq(&other.0) + } +} + +impl, U: TrustedEntityBorrow> PartialEq<&UniqueEntitySlice> for Vec { + fn eq(&self, other: &&UniqueEntitySlice) -> bool { + self.eq(&other.0) + } +} + +impl, U: TrustedEntityBorrow> PartialEq<&UniqueEntitySlice> for VecDeque { + fn eq(&self, other: &&UniqueEntitySlice) -> bool { + self.eq(&&other.0) + } +} + +impl, U: TrustedEntityBorrow, const N: usize> PartialEq<&mut UniqueEntitySlice> + for [T; N] +{ + fn eq(&self, other: &&mut UniqueEntitySlice) -> bool { + self.eq(&other.0) + } +} + +impl + Clone, U: TrustedEntityBorrow> PartialEq<&mut UniqueEntitySlice> + for Cow<'_, [T]> +{ + fn eq(&self, other: &&mut UniqueEntitySlice) -> bool { + self.eq(&&**other) + } +} + +impl + Clone, U: TrustedEntityBorrow> + PartialEq<&mut UniqueEntitySlice> for Cow<'_, UniqueEntitySlice> +{ + fn eq(&self, other: &&mut UniqueEntitySlice) -> bool { + self.0.eq(&other.0) + } +} + +impl + Clone, U: TrustedEntityBorrow> + PartialEq> for Cow<'_, UniqueEntitySlice> +{ + fn eq(&self, other: &UniqueEntityVec) -> bool { + self.0.eq(other.as_vec()) + } +} + +impl, U: TrustedEntityBorrow> PartialEq<&mut UniqueEntitySlice> for Vec { + fn eq(&self, other: &&mut UniqueEntitySlice) -> bool { + self.eq(&other.0) + } +} + +impl, U: TrustedEntityBorrow> PartialEq<&mut UniqueEntitySlice> for VecDeque { + fn eq(&self, other: &&mut UniqueEntitySlice) -> bool { + self.eq(&&other.0) + } +} + +impl, U: TrustedEntityBorrow> PartialEq> + for [T] +{ + fn eq(&self, other: &UniqueEntitySlice) -> bool { + self.eq(&other.0) + } +} + +impl, U: TrustedEntityBorrow, const N: usize> PartialEq> + for [T; N] +{ + fn eq(&self, other: &UniqueEntitySlice) -> bool { + self.eq(&other.0) + } +} + +impl, U: TrustedEntityBorrow> PartialEq> + for Vec +{ + fn eq(&self, other: &UniqueEntitySlice) -> bool { + self.eq(&other.0) + } +} + +impl, U, const N: usize> PartialEq<[U; N]> + for &UniqueEntitySlice +{ + fn eq(&self, other: &[U; N]) -> bool { + self.0.eq(other) + } +} + +impl, U, const N: usize> PartialEq<[U; N]> + for &mut UniqueEntitySlice +{ + fn eq(&self, other: &[U; N]) -> bool { + self.0.eq(other) + } +} + +impl, U, const N: usize> PartialEq<[U; N]> + for UniqueEntitySlice +{ + fn eq(&self, other: &[U; N]) -> bool { + self.0.eq(other) + } +} + +impl, U> PartialEq> for &UniqueEntitySlice { + fn eq(&self, other: &Vec) -> bool { + self.0.eq(other) + } +} + +impl, U> PartialEq> for &mut UniqueEntitySlice { + fn eq(&self, other: &Vec) -> bool { + self.0.eq(other) + } +} + +impl, U> PartialEq> for UniqueEntitySlice { + fn eq(&self, other: &Vec) -> bool { + self.0.eq(other) + } +} + +impl ToOwned for UniqueEntitySlice { + type Owned = UniqueEntityVec; + + fn to_owned(&self) -> Self::Owned { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntityVec::from_vec_unchecked(self.0.to_owned()) } + } +} + +impl Index<(Bound, Bound)> for UniqueEntitySlice { + type Output = Self; + fn index(&self, key: (Bound, Bound)) -> &Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index> for UniqueEntitySlice { + type Output = Self; + fn index(&self, key: Range) -> &Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index> for UniqueEntitySlice { + type Output = Self; + fn index(&self, key: RangeFrom) -> &Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index for UniqueEntitySlice { + type Output = Self; + fn index(&self, key: RangeFull) -> &Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index> for UniqueEntitySlice { + type Output = UniqueEntitySlice; + fn index(&self, key: RangeInclusive) -> &Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index> for UniqueEntitySlice { + type Output = UniqueEntitySlice; + fn index(&self, key: RangeTo) -> &Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index> for UniqueEntitySlice { + type Output = UniqueEntitySlice; + fn index(&self, key: RangeToInclusive) -> &Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index for UniqueEntitySlice { + type Output = T; + + fn index(&self, index: usize) -> &T { + &self.0[index] + } +} + +impl IndexMut<(Bound, Bound)> for UniqueEntitySlice { + fn index_mut(&mut self, key: (Bound, Bound)) -> &mut Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut> for UniqueEntitySlice { + fn index_mut(&mut self, key: Range) -> &mut Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut> for UniqueEntitySlice { + fn index_mut(&mut self, key: RangeFrom) -> &mut Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut for UniqueEntitySlice { + fn index_mut(&mut self, key: RangeFull) -> &mut Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut> for UniqueEntitySlice { + fn index_mut(&mut self, key: RangeInclusive) -> &mut Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut> for UniqueEntitySlice { + fn index_mut(&mut self, key: RangeTo) -> &mut Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut> for UniqueEntitySlice { + fn index_mut(&mut self, key: RangeToInclusive) -> &mut Self { + // SAFETY: All elements in the original slice are unique. + unsafe { Self::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +/// Immutable slice iterator. +/// +/// This struct is created by [`iter`] method on [`UniqueEntitySlice`] and +/// the [`IntoIterator`] impls on it and [`UniqueEntityVec`]. +/// +/// [`iter`]: `UniqueEntitySlice::iter` +/// [`into_iter`]: UniqueEntitySlice::into_iter +pub type Iter<'a, T> = UniqueEntityIter>; + +impl<'a, T: TrustedEntityBorrow> UniqueEntityIter> { + /// Views the underlying data as a subslice of the original data. + /// + /// Equivalent to [`slice::Iter::as_slice`]. + pub fn as_slice(&self) -> &'a UniqueEntitySlice { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.as_inner().as_slice()) } + } +} + +/// Mutable slice iterator. +pub type IterMut<'a, T> = UniqueEntityIter>; + +impl<'a, T: TrustedEntityBorrow> UniqueEntityIter> { + /// Views the underlying data as a mutable subslice of the original data. + /// + /// Equivalent to [`slice::IterMut::into_slice`]. + pub fn into_slice(self) -> &'a mut UniqueEntitySlice { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.into_inner().into_slice()) } + } + + /// Views the underlying data as a subslice of the original data. + /// + /// Equivalent to [`slice::IterMut::as_slice`]. + pub fn as_slice(&self) -> &UniqueEntitySlice { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.as_inner().as_slice()) } + } +} diff --git a/crates/bevy_ecs/src/entity/unique_vec.rs b/crates/bevy_ecs/src/entity/unique_vec.rs index 32b4f0b03751f..9ea1f9c7a6b39 100644 --- a/crates/bevy_ecs/src/entity/unique_vec.rs +++ b/crates/bevy_ecs/src/entity/unique_vec.rs @@ -1,12 +1,14 @@ use core::{ - borrow::Borrow, + borrow::{Borrow, BorrowMut}, mem::MaybeUninit, - ops::{Index, RangeBounds}, - slice, + ops::{ + Bound, Deref, DerefMut, Index, IndexMut, Range, RangeBounds, RangeFrom, RangeFull, + RangeInclusive, RangeTo, RangeToInclusive, + }, }; use alloc::{ - borrow::Cow, + borrow::{Cow, ToOwned}, boxed::Box, collections::{BTreeSet, BinaryHeap, TryReserveError, VecDeque}, rc::Rc, @@ -14,7 +16,10 @@ use alloc::{ vec::{self, Vec}, }; -use super::{EntitySet, FromEntitySetIterator, TrustedEntityBorrow, UniqueEntityIter}; +use super::{ + unique_slice, EntitySet, FromEntitySetIterator, TrustedEntityBorrow, UniqueEntityIter, + UniqueEntitySlice, +}; /// A `Vec` that contains only unique entities. /// @@ -140,6 +145,22 @@ impl UniqueEntityVec { self.0.shrink_to(min_capacity); } + /// Converts the vector into `Box>`. + pub fn into_boxed_slice(self) -> Box> { + // SAFETY: UniqueEntitySlice is a transparent wrapper around [T]. + unsafe { UniqueEntitySlice::from_boxed_slice_unchecked(self.0.into_boxed_slice()) } + } + + /// Extracts a slice containing the entire vector. + pub fn as_slice(&self) -> &UniqueEntitySlice { + self + } + + /// Extracts a mutable slice of the entire vector. + pub fn as_mut_slice(&mut self) -> &mut UniqueEntitySlice { + self + } + /// Shortens the vector, keeping the first `len` elements and dropping /// the rest. /// @@ -343,6 +364,12 @@ impl UniqueEntityVec { self.0.resize_with(new_len, f); } + /// Consumes and leaks the Vec, returning a mutable reference to the contents, `&'a mut UniqueEntitySlice`. + pub fn leak<'a>(self) -> &'a mut UniqueEntitySlice { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.0.leak()) } + } + /// Returns the remaining spare capacity of the vector as a slice of /// [`MaybeUninit`]. /// @@ -370,7 +397,7 @@ impl UniqueEntityVec { I: EntitySet, { // SAFETY: `self` and thus `range` contains only unique elements. - UniqueEntityIter::from_iterator_unchecked(self.0.splice(range, replace_with)) + unsafe { UniqueEntityIter::from_iterator_unchecked(self.0.splice(range, replace_with)) } } } @@ -380,13 +407,29 @@ impl Default for UniqueEntityVec { } } +impl Deref for UniqueEntityVec { + type Target = UniqueEntitySlice; + + fn deref(&self) -> &Self::Target { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(&self.0) } + } +} + +impl DerefMut for UniqueEntityVec { + fn deref_mut(&mut self) -> &mut Self::Target { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(&mut self.0) } + } +} + impl<'a, T: TrustedEntityBorrow> IntoIterator for &'a UniqueEntityVec where &'a T: TrustedEntityBorrow, { type Item = &'a T; - type IntoIter = UniqueEntityIter>; + type IntoIter = unique_slice::Iter<'a, T>; fn into_iter(self) -> Self::IntoIter { // SAFETY: `self` contains only unique elements. @@ -411,6 +454,12 @@ impl AsMut for UniqueEntityVec { } } +impl AsMut> for UniqueEntityVec { + fn as_mut(&mut self) -> &mut UniqueEntitySlice { + self + } +} + impl AsRef for UniqueEntityVec { fn as_ref(&self) -> &Self { self @@ -435,12 +484,30 @@ impl AsRef<[T]> for UniqueEntityVec { } } +impl AsRef> for UniqueEntityVec { + fn as_ref(&self) -> &UniqueEntitySlice { + self + } +} + impl Borrow<[T]> for UniqueEntityVec { fn borrow(&self) -> &[T] { &self.0 } } +impl Borrow> for UniqueEntityVec { + fn borrow(&self) -> &UniqueEntitySlice { + self + } +} + +impl BorrowMut> for UniqueEntityVec { + fn borrow_mut(&mut self) -> &mut UniqueEntitySlice { + self + } +} + impl, U> PartialEq> for UniqueEntityVec { fn eq(&self, other: &Vec) -> bool { self.0.eq(other) @@ -453,12 +520,28 @@ impl, U> PartialEq<&[U]> for UniqueEntityV } } +impl, U: TrustedEntityBorrow> PartialEq<&UniqueEntitySlice> + for UniqueEntityVec +{ + fn eq(&self, other: &&UniqueEntitySlice) -> bool { + self.0.eq(other) + } +} + impl, U> PartialEq<&mut [U]> for UniqueEntityVec { fn eq(&self, other: &&mut [U]) -> bool { self.0.eq(other) } } +impl, U: TrustedEntityBorrow> + PartialEq<&mut UniqueEntitySlice> for UniqueEntityVec +{ + fn eq(&self, other: &&mut UniqueEntitySlice) -> bool { + self.0.eq(other) + } +} + impl, U, const N: usize> PartialEq<&[U; N]> for UniqueEntityVec { @@ -481,6 +564,14 @@ impl, U> PartialEq<[U]> for UniqueEntityVe } } +impl, U: TrustedEntityBorrow> PartialEq> + for UniqueEntityVec +{ + fn eq(&self, other: &UniqueEntitySlice) -> bool { + self.0.eq(&**other) + } +} + impl, U, const N: usize> PartialEq<[U; N]> for UniqueEntityVec { @@ -529,6 +620,33 @@ impl, U: TrustedEntityBorrow> PartialEq> for } } +impl From<&UniqueEntitySlice> for UniqueEntityVec { + fn from(value: &UniqueEntitySlice) -> Self { + value.to_vec() + } +} + +impl From<&mut UniqueEntitySlice> for UniqueEntityVec { + fn from(value: &mut UniqueEntitySlice) -> Self { + value.to_vec() + } +} + +impl From>> for UniqueEntityVec { + fn from(value: Box>) -> Self { + value.into_vec() + } +} + +impl From>> for UniqueEntityVec +where + UniqueEntitySlice: ToOwned>, +{ + fn from(value: Cow>) -> Self { + value.into_owned() + } +} + impl From<&[T; 1]> for UniqueEntityVec { fn from(value: &[T; 1]) -> Self { Self(Vec::from(value)) @@ -577,12 +695,27 @@ impl<'a, T: TrustedEntityBorrow + Clone> From> for Cow<'a, [T } } +impl<'a, T: TrustedEntityBorrow + Clone> From> + for Cow<'a, UniqueEntitySlice> +{ + fn from(value: UniqueEntityVec) -> Self { + Cow::Owned(value) + } +} + impl From> for Arc<[T]> { fn from(value: UniqueEntityVec) -> Self { Arc::from(value.0) } } +impl From> for Arc> { + fn from(value: UniqueEntityVec) -> Self { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_arc_slice_unchecked(Arc::from(value.0)) } + } +} + impl From> for BinaryHeap { fn from(value: UniqueEntityVec) -> Self { BinaryHeap::from(value.0) @@ -601,6 +734,13 @@ impl From> for Rc<[T]> { } } +impl From> for Rc> { + fn from(value: UniqueEntityVec) -> Self { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_rc_slice_unchecked(Rc::from(value.0)) } + } +} + impl From> for VecDeque { fn from(value: UniqueEntityVec) -> Self { VecDeque::from(value.0) @@ -709,6 +849,62 @@ impl<'a, T: TrustedEntityBorrow + Copy + 'a> Extend<&'a T> for UniqueEntityVec Index<(Bound, Bound)> for UniqueEntityVec { + type Output = UniqueEntitySlice; + fn index(&self, key: (Bound, Bound)) -> &Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index> for UniqueEntityVec { + type Output = UniqueEntitySlice; + fn index(&self, key: Range) -> &Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index> for UniqueEntityVec { + type Output = UniqueEntitySlice; + fn index(&self, key: RangeFrom) -> &Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index for UniqueEntityVec { + type Output = UniqueEntitySlice; + fn index(&self, key: RangeFull) -> &Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index> for UniqueEntityVec { + type Output = UniqueEntitySlice; + fn index(&self, key: RangeInclusive) -> &Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index> for UniqueEntityVec { + type Output = UniqueEntitySlice; + fn index(&self, key: RangeTo) -> &Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.0.index(key)) } + } +} + +impl Index> for UniqueEntityVec { + type Output = UniqueEntitySlice; + fn index(&self, key: RangeToInclusive) -> &Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.0.index(key)) } + } +} + impl Index for UniqueEntityVec { type Output = T; fn index(&self, key: usize) -> &T { @@ -716,20 +912,97 @@ impl Index for UniqueEntityVec { } } +impl IndexMut<(Bound, Bound)> for UniqueEntityVec { + fn index_mut(&mut self, key: (Bound, Bound)) -> &mut Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut> for UniqueEntityVec { + fn index_mut(&mut self, key: Range) -> &mut Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut> for UniqueEntityVec { + fn index_mut(&mut self, key: RangeFrom) -> &mut Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut for UniqueEntityVec { + fn index_mut(&mut self, key: RangeFull) -> &mut Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut> for UniqueEntityVec { + fn index_mut(&mut self, key: RangeInclusive) -> &mut Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut> for UniqueEntityVec { + fn index_mut(&mut self, key: RangeTo) -> &mut Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +impl IndexMut> for UniqueEntityVec { + fn index_mut(&mut self, key: RangeToInclusive) -> &mut Self::Output { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.0.index_mut(key)) } + } +} + +/// An iterator that moves out of a vector. +/// +/// This `struct` is created by the [`IntoIterator::into_iter`] trait +/// method on [`UniqueEntityVec`]. +pub type IntoIter = UniqueEntityIter>; + +impl UniqueEntityIter> { + /// Returns the remaining items of this iterator as a slice. + /// + /// Equivalent to [`vec::IntoIter::as_slice`]. + pub fn as_slice(&self) -> &UniqueEntitySlice { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.as_inner().as_slice()) } + } + + /// Returns the remaining items of this iterator as a mutable slice. + /// + /// Equivalent to [`vec::IntoIter::as_mut_slice`]. + pub fn as_mut_slice(&mut self) -> &mut UniqueEntitySlice { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked_mut(self.as_mut_inner().as_mut_slice()) } + } +} + /// A draining iterator for [`UniqueEntityVec`]. /// /// This struct is created by [`UniqueEntityVec::drain`]. /// See its documentation for more. pub type Drain<'a, T> = UniqueEntityIter>; +impl<'a, T: TrustedEntityBorrow> UniqueEntityIter> { + /// Returns the remaining items of this iterator as a slice. + /// + /// Equivalent to [`vec::Drain::as_slice`]. + pub fn as_slice(&self) -> &UniqueEntitySlice { + // SAFETY: All elements in the original slice are unique. + unsafe { UniqueEntitySlice::from_slice_unchecked(self.as_inner().as_slice()) } + } +} + /// A splicing iterator for [`UniqueEntityVec`]. /// /// This struct is created by [`UniqueEntityVec::splice`]. /// See its documentation for more. pub type Splice<'a, I> = UniqueEntityIter>; - -/// An iterator that moves out of a vector. -/// -/// This `struct` is created by the [`IntoIterator::into_iter`] trait -/// method on [`UniqueEntityVec`]. -pub type IntoIter = UniqueEntityIter>;