Path: blob/main/crates/bevy_platform/src/collections/hash_set.rs
9356 views
//! Provides [`HashSet`] based on [hashbrown]'s implementation.1//! Unlike [`hashbrown::HashSet`], [`HashSet`] defaults to [`FixedHasher`]2//! instead of [`RandomState`](crate::hash::RandomState).3//! This provides determinism by default with an acceptable compromise to denial4//! of service resistance in the context of a game engine.56use core::{7fmt::Debug,8hash::{BuildHasher, Hash},9ops::{10BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Deref, DerefMut, Sub,11SubAssign,12},13};1415use hashbrown::{hash_set as hb, Equivalent};1617use crate::hash::FixedHasher;1819#[cfg(feature = "rayon")]20use rayon::prelude::{FromParallelIterator, IntoParallelIterator, ParallelExtend};2122// Re-exports to match `std::collections::hash_set`23pub use hb::{Difference, Drain, Intersection, IntoIter, Iter, SymmetricDifference, Union};2425// Additional items from `hashbrown`26pub use hb::{ExtractIf, OccupiedEntry, VacantEntry};2728/// Shortcut for [`Entry`](hb::Entry) with [`FixedHasher`] as the default hashing provider.29pub type Entry<'a, T, S = FixedHasher> = hb::Entry<'a, T, S>;3031/// New-type for [`HashSet`](hb::HashSet) with [`FixedHasher`] as the default hashing provider.32/// Can be trivially converted to and from a [hashbrown] [`HashSet`](hb::HashSet) using [`From`].33///34/// A new-type is used instead of a type alias due to critical methods like [`new`](hb::HashSet::new)35/// being incompatible with Bevy's choice of default hasher.36///37/// Unlike [`hashbrown::HashSet`], [`HashSet`] defaults to [`FixedHasher`]38/// instead of [`RandomState`](crate::hash::RandomState).39/// This provides determinism by default with an acceptable compromise to denial40/// of service resistance in the context of a game engine.41#[repr(transparent)]42pub struct HashSet<T, S = FixedHasher>(hb::HashSet<T, S>);4344impl<T, S> Clone for HashSet<T, S>45where46hb::HashSet<T, S>: Clone,47{48#[inline]49fn clone(&self) -> Self {50Self(self.0.clone())51}5253#[inline]54fn clone_from(&mut self, source: &Self) {55self.0.clone_from(&source.0);56}57}5859impl<T, S> Debug for HashSet<T, S>60where61hb::HashSet<T, S>: Debug,62{63#[inline]64fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {65<hb::HashSet<T, S> as Debug>::fmt(&self.0, f)66}67}6869impl<T, S> Default for HashSet<T, S>70where71hb::HashSet<T, S>: Default,72{73#[inline]74fn default() -> Self {75Self(Default::default())76}77}7879impl<T, S> PartialEq for HashSet<T, S>80where81hb::HashSet<T, S>: PartialEq,82{83#[inline]84fn eq(&self, other: &Self) -> bool {85self.0.eq(&other.0)86}87}8889impl<T, S> Eq for HashSet<T, S> where hb::HashSet<T, S>: Eq {}9091impl<T, S, X> FromIterator<X> for HashSet<T, S>92where93hb::HashSet<T, S>: FromIterator<X>,94{95#[inline]96fn from_iter<U: IntoIterator<Item = X>>(iter: U) -> Self {97Self(FromIterator::from_iter(iter))98}99}100101impl<T, S> IntoIterator for HashSet<T, S>102where103hb::HashSet<T, S>: IntoIterator,104{105type Item = <hb::HashSet<T, S> as IntoIterator>::Item;106107type IntoIter = <hb::HashSet<T, S> as IntoIterator>::IntoIter;108109#[inline]110fn into_iter(self) -> Self::IntoIter {111self.0.into_iter()112}113}114115impl<'a, T, S> IntoIterator for &'a HashSet<T, S>116where117&'a hb::HashSet<T, S>: IntoIterator,118{119type Item = <&'a hb::HashSet<T, S> as IntoIterator>::Item;120121type IntoIter = <&'a hb::HashSet<T, S> as IntoIterator>::IntoIter;122123#[inline]124fn into_iter(self) -> Self::IntoIter {125(&self.0).into_iter()126}127}128129impl<'a, T, S> IntoIterator for &'a mut HashSet<T, S>130where131&'a mut hb::HashSet<T, S>: IntoIterator,132{133type Item = <&'a mut hb::HashSet<T, S> as IntoIterator>::Item;134135type IntoIter = <&'a mut hb::HashSet<T, S> as IntoIterator>::IntoIter;136137#[inline]138fn into_iter(self) -> Self::IntoIter {139(&mut self.0).into_iter()140}141}142143impl<T, S, X> Extend<X> for HashSet<T, S>144where145hb::HashSet<T, S>: Extend<X>,146{147#[inline]148fn extend<U: IntoIterator<Item = X>>(&mut self, iter: U) {149self.0.extend(iter);150}151}152153impl<T, const N: usize> From<[T; N]> for HashSet<T, FixedHasher>154where155T: Eq + Hash,156{157fn from(value: [T; N]) -> Self {158value.into_iter().collect()159}160}161162impl<T, S> From<crate::collections::HashMap<T, (), S>> for HashSet<T, S> {163#[inline]164fn from(value: crate::collections::HashMap<T, (), S>) -> Self {165Self(hb::HashSet::from(hashbrown::HashMap::from(value)))166}167}168169impl<T, S> From<hb::HashSet<T, S>> for HashSet<T, S> {170#[inline]171fn from(value: hb::HashSet<T, S>) -> Self {172Self(value)173}174}175176impl<T, S> From<HashSet<T, S>> for hb::HashSet<T, S> {177#[inline]178fn from(value: HashSet<T, S>) -> Self {179value.0180}181}182183impl<T, S> Deref for HashSet<T, S> {184type Target = hb::HashSet<T, S>;185186#[inline]187fn deref(&self) -> &Self::Target {188&self.0189}190}191192impl<T, S> DerefMut for HashSet<T, S> {193#[inline]194fn deref_mut(&mut self) -> &mut Self::Target {195&mut self.0196}197}198199#[cfg(feature = "serialize")]200impl<T, S> serde::Serialize for HashSet<T, S>201where202hb::HashSet<T, S>: serde::Serialize,203{204#[inline]205fn serialize<U>(&self, serializer: U) -> Result<U::Ok, U::Error>206where207U: serde::Serializer,208{209self.0.serialize(serializer)210}211}212213#[cfg(feature = "serialize")]214impl<'de, T, S> serde::Deserialize<'de> for HashSet<T, S>215where216hb::HashSet<T, S>: serde::Deserialize<'de>,217{218#[inline]219fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>220where221D: serde::Deserializer<'de>,222{223Ok(Self(serde::Deserialize::deserialize(deserializer)?))224}225}226227#[cfg(feature = "rayon")]228impl<T, S, U> FromParallelIterator<U> for HashSet<T, S>229where230hb::HashSet<T, S>: FromParallelIterator<U>,231U: Send,232{233fn from_par_iter<P>(par_iter: P) -> Self234where235P: IntoParallelIterator<Item = U>,236{237Self(<hb::HashSet<T, S> as FromParallelIterator<U>>::from_par_iter(par_iter))238}239}240241#[cfg(feature = "rayon")]242impl<T, S> IntoParallelIterator for HashSet<T, S>243where244hb::HashSet<T, S>: IntoParallelIterator,245{246type Item = <hb::HashSet<T, S> as IntoParallelIterator>::Item;247type Iter = <hb::HashSet<T, S> as IntoParallelIterator>::Iter;248249fn into_par_iter(self) -> Self::Iter {250self.0.into_par_iter()251}252}253254#[cfg(feature = "rayon")]255impl<'a, T: Sync, S> IntoParallelIterator for &'a HashSet<T, S>256where257&'a hb::HashSet<T, S>: IntoParallelIterator,258{259type Item = <&'a hb::HashSet<T, S> as IntoParallelIterator>::Item;260type Iter = <&'a hb::HashSet<T, S> as IntoParallelIterator>::Iter;261262fn into_par_iter(self) -> Self::Iter {263(&self.0).into_par_iter()264}265}266267#[cfg(feature = "rayon")]268impl<T, S, U> ParallelExtend<U> for HashSet<T, S>269where270hb::HashSet<T, S>: ParallelExtend<U>,271U: Send,272{273fn par_extend<I>(&mut self, par_iter: I)274where275I: IntoParallelIterator<Item = U>,276{277<hb::HashSet<T, S> as ParallelExtend<U>>::par_extend(&mut self.0, par_iter);278}279}280281impl<T> HashSet<T, FixedHasher> {282/// Creates an empty [`HashSet`].283///284/// Refer to [`new`](hb::HashSet::new) for further details.285///286/// # Examples287///288/// ```rust289/// # use bevy_platform::collections::HashSet;290/// #291/// // Creates a HashSet with zero capacity.292/// let map = HashSet::new();293/// #294/// # let mut map = map;295/// # map.insert("foo");296/// # assert_eq!(map.get("foo"), Some("foo").as_ref());297/// ```298#[inline]299pub const fn new() -> Self {300Self::with_hasher(FixedHasher)301}302303/// Creates an empty [`HashSet`] with the specified capacity.304///305/// Refer to [`with_capacity`](hb::HashSet::with_capacity) for further details.306///307/// # Examples308///309/// ```rust310/// # use bevy_platform::collections::HashSet;311/// #312/// // Creates a HashSet with capacity for at least 5 entries.313/// let map = HashSet::with_capacity(5);314/// #315/// # let mut map = map;316/// # map.insert("foo");317/// # assert_eq!(map.get("foo"), Some("foo").as_ref());318/// ```319#[inline]320pub fn with_capacity(capacity: usize) -> Self {321Self::with_capacity_and_hasher(capacity, FixedHasher)322}323}324325impl<T, S> HashSet<T, S> {326/// Returns the number of elements the set can hold without reallocating.327///328/// Refer to [`capacity`](hb::HashSet::capacity) for further details.329///330/// # Examples331///332/// ```rust333/// # use bevy_platform::collections::HashSet;334/// let map = HashSet::with_capacity(5);335///336/// # let map: HashSet<()> = map;337/// #338/// assert!(map.capacity() >= 5);339/// ```340#[inline]341pub fn capacity(&self) -> usize {342self.0.capacity()343}344345/// An iterator visiting all elements in arbitrary order.346/// The iterator element type is `&'a T`.347///348/// Refer to [`iter`](hb::HashSet::iter) for further details.349///350/// # Examples351///352/// ```rust353/// # use bevy_platform::collections::HashSet;354/// #355/// let mut map = HashSet::new();356///357/// map.insert("foo");358/// map.insert("bar");359/// map.insert("baz");360///361/// for value in map.iter() {362/// // "foo", "bar", "baz"363/// // Note that the above order is not guaranteed364/// }365/// #366/// # assert_eq!(map.iter().count(), 3);367/// ```368#[inline]369pub fn iter(&self) -> Iter<'_, T> {370self.0.iter()371}372373/// Returns the number of elements in the set.374///375/// Refer to [`len`](hb::HashSet::len) for further details.376///377/// # Examples378///379/// ```rust380/// # use bevy_platform::collections::HashSet;381/// let mut map = HashSet::new();382///383/// assert_eq!(map.len(), 0);384///385/// map.insert("foo");386///387/// assert_eq!(map.len(), 1);388/// ```389#[inline]390pub fn len(&self) -> usize {391self.0.len()392}393394/// Returns `true` if the set contains no elements.395///396/// Refer to [`is_empty`](hb::HashSet::is_empty) for further details.397///398/// # Examples399///400/// ```rust401/// # use bevy_platform::collections::HashSet;402/// let mut map = HashSet::new();403///404/// assert!(map.is_empty());405///406/// map.insert("foo");407///408/// assert!(!map.is_empty());409/// ```410#[inline]411pub fn is_empty(&self) -> bool {412self.0.is_empty()413}414415/// Clears the set, returning all elements in an iterator.416///417/// Refer to [`drain`](hb::HashSet::drain) for further details.418///419/// # Examples420///421/// ```rust422/// # use bevy_platform::collections::HashSet;423/// #424/// let mut map = HashSet::new();425///426/// map.insert("foo");427/// map.insert("bar");428/// map.insert("baz");429///430/// for value in map.drain() {431/// // "foo", "bar", "baz"432/// // Note that the above order is not guaranteed433/// }434///435/// assert!(map.is_empty());436/// ```437#[inline]438pub fn drain(&mut self) -> Drain<'_, T> {439self.0.drain()440}441442/// Retains only the elements specified by the predicate.443///444/// Refer to [`retain`](hb::HashSet::retain) for further details.445///446/// # Examples447///448/// ```rust449/// # use bevy_platform::collections::HashSet;450/// #451/// let mut map = HashSet::new();452///453/// map.insert("foo");454/// map.insert("bar");455/// map.insert("baz");456///457/// map.retain(|value| *value == "baz");458///459/// assert_eq!(map.len(), 1);460/// ```461#[inline]462pub fn retain<F>(&mut self, f: F)463where464F: FnMut(&T) -> bool,465{466self.0.retain(f);467}468469/// Drains elements which are true under the given predicate,470/// and returns an iterator over the removed items.471///472/// Refer to [`extract_if`](hb::HashSet::extract_if) for further details.473///474/// # Examples475///476/// ```rust477/// # use bevy_platform::collections::HashSet;478/// #479/// let mut map = HashSet::new();480///481/// map.insert("foo");482/// map.insert("bar");483/// map.insert("baz");484///485/// let extracted = map486/// .extract_if(|value| *value == "baz")487/// .collect::<Vec<_>>();488///489/// assert_eq!(map.len(), 2);490/// assert_eq!(extracted.len(), 1);491/// ```492#[inline]493pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, T, F>494where495F: FnMut(&T) -> bool,496{497self.0.extract_if(f)498}499500/// Clears the set, removing all values.501///502/// Refer to [`clear`](hb::HashSet::clear) for further details.503///504/// # Examples505///506/// ```rust507/// # use bevy_platform::collections::HashSet;508/// #509/// let mut map = HashSet::new();510///511/// map.insert("foo");512/// map.insert("bar");513/// map.insert("baz");514///515/// map.clear();516///517/// assert!(map.is_empty());518/// ```519#[inline]520pub fn clear(&mut self) {521self.0.clear();522}523524/// Creates a new empty hash set which will use the given hasher to hash525/// keys.526///527/// Refer to [`with_hasher`](hb::HashSet::with_hasher) for further details.528///529/// # Examples530///531/// ```rust532/// # use bevy_platform::collections::HashSet;533/// # use bevy_platform::hash::FixedHasher as SomeHasher;534/// // Creates a HashSet with the provided hasher.535/// let map = HashSet::with_hasher(SomeHasher);536/// #537/// # let mut map = map;538/// # map.insert("foo");539/// # assert_eq!(map.get("foo"), Some("foo").as_ref());540/// ```541#[inline]542pub const fn with_hasher(hasher: S) -> Self {543Self(hb::HashSet::with_hasher(hasher))544}545546/// Creates an empty [`HashSet`] with the specified capacity, using547/// `hasher` to hash the keys.548///549/// Refer to [`with_capacity_and_hasher`](hb::HashSet::with_capacity_and_hasher) for further details.550///551/// # Examples552///553/// ```rust554/// # use bevy_platform::collections::HashSet;555/// # use bevy_platform::hash::FixedHasher as SomeHasher;556/// // Creates a HashSet with capacity for 5 entries and the provided hasher.557/// let map = HashSet::with_capacity_and_hasher(5, SomeHasher);558/// #559/// # let mut map = map;560/// # map.insert("foo");561/// # assert_eq!(map.get("foo"), Some("foo").as_ref());562/// ```563#[inline]564pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {565Self(hb::HashSet::with_capacity_and_hasher(capacity, hasher))566}567568/// Returns a reference to the set's [`BuildHasher`].569///570/// Refer to [`hasher`](hb::HashSet::hasher) for further details.571#[inline]572pub fn hasher(&self) -> &S {573self.0.hasher()574}575576/// Takes the inner [`HashSet`](hb::HashSet) out of this wrapper.577///578/// # Examples579///580/// ```rust581/// # use bevy_platform::collections::HashSet;582/// let map: HashSet<&'static str> = HashSet::new();583/// let map: hashbrown::HashSet<&'static str, _> = map.into_inner();584/// ```585#[inline]586pub fn into_inner(self) -> hb::HashSet<T, S> {587self.0588}589}590591impl<T, S> HashSet<T, S>592where593T: Eq + Hash,594S: BuildHasher,595{596/// Reserves capacity for at least `additional` more elements to be inserted597/// in the [`HashSet`]. The collection may reserve more space to avoid598/// frequent reallocations.599///600/// Refer to [`reserve`](hb::HashSet::reserve) for further details.601///602/// # Examples603///604/// ```rust605/// # use bevy_platform::collections::HashSet;606/// let mut map = HashSet::with_capacity(5);607///608/// # let mut map: HashSet<()> = map;609/// #610/// assert!(map.capacity() >= 5);611///612/// map.reserve(10);613///614/// assert!(map.capacity() - map.len() >= 10);615/// ```616#[inline]617pub fn reserve(&mut self, additional: usize) {618self.0.reserve(additional);619}620621/// Tries to reserve capacity for at least `additional` more elements to be inserted622/// in the given `HashSet<K,V>`. The collection may reserve more space to avoid623/// frequent reallocations.624///625/// Refer to [`try_reserve`](hb::HashSet::try_reserve) for further details.626///627/// # Examples628///629/// ```rust630/// # use bevy_platform::collections::HashSet;631/// let mut map = HashSet::with_capacity(5);632///633/// # let mut map: HashSet<()> = map;634/// #635/// assert!(map.capacity() >= 5);636///637/// map.try_reserve(10).expect("Out of Memory!");638///639/// assert!(map.capacity() - map.len() >= 10);640/// ```641#[inline]642pub fn try_reserve(&mut self, additional: usize) -> Result<(), hashbrown::TryReserveError> {643self.0.try_reserve(additional)644}645646/// Shrinks the capacity of the set as much as possible. It will drop647/// down as much as possible while maintaining the internal rules648/// and possibly leaving some space in accordance with the resize policy.649///650/// Refer to [`shrink_to_fit`](hb::HashSet::shrink_to_fit) for further details.651///652/// # Examples653///654/// ```rust655/// # use bevy_platform::collections::HashSet;656/// let mut map = HashSet::with_capacity(5);657///658/// map.insert("foo");659/// map.insert("bar");660/// map.insert("baz");661///662/// assert!(map.capacity() >= 5);663///664/// map.shrink_to_fit();665///666/// assert_eq!(map.capacity(), 3);667/// ```668#[inline]669pub fn shrink_to_fit(&mut self) {670self.0.shrink_to_fit();671}672673/// Shrinks the capacity of the set with a lower limit. It will drop674/// down no lower than the supplied limit while maintaining the internal rules675/// and possibly leaving some space in accordance with the resize policy.676///677/// Refer to [`shrink_to`](hb::HashSet::shrink_to) for further details.678#[inline]679pub fn shrink_to(&mut self, min_capacity: usize) {680self.0.shrink_to(min_capacity);681}682683/// Visits the values representing the difference,684/// i.e., the values that are in `self` but not in `other`.685///686/// Refer to [`difference`](hb::HashSet::difference) for further details.687#[inline]688pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, T, S> {689self.0.difference(other)690}691692/// Visits the values representing the symmetric difference,693/// i.e., the values that are in `self` or in `other` but not in both.694///695/// Refer to [`symmetric_difference`](hb::HashSet::symmetric_difference) for further details.696#[inline]697pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, T, S> {698self.0.symmetric_difference(other)699}700701/// Visits the values representing the intersection,702/// i.e., the values that are both in `self` and `other`.703///704/// Refer to [`intersection`](hb::HashSet::intersection) for further details.705#[inline]706pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T, S> {707self.0.intersection(other)708}709710/// Visits the values representing the union,711/// i.e., all the values in `self` or `other`, without duplicates.712///713/// Refer to [`union`](hb::HashSet::union) for further details.714#[inline]715pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T, S> {716self.0.union(other)717}718719/// Returns `true` if the set contains a value.720///721/// Refer to [`contains`](hb::HashSet::contains) for further details.722///723/// # Examples724///725/// ```rust726/// # use bevy_platform::collections::HashSet;727/// let mut map = HashSet::new();728///729/// map.insert("foo");730///731/// assert!(map.contains("foo"));732/// ```733#[inline]734pub fn contains<Q>(&self, value: &Q) -> bool735where736Q: Hash + Equivalent<T> + ?Sized,737{738self.0.contains(value)739}740741/// Returns a reference to the value in the set, if any, that is equal to the given value.742///743/// Refer to [`get`](hb::HashSet::get) for further details.744///745/// # Examples746///747/// ```rust748/// # use bevy_platform::collections::HashSet;749/// let mut map = HashSet::new();750///751/// map.insert("foo");752///753/// assert_eq!(map.get("foo"), Some(&"foo"));754/// ```755#[inline]756pub fn get<Q>(&self, value: &Q) -> Option<&T>757where758Q: Hash + Equivalent<T> + ?Sized,759{760self.0.get(value)761}762763/// Inserts the given `value` into the set if it is not present, then764/// returns a reference to the value in the set.765///766/// Refer to [`get_or_insert`](hb::HashSet::get_or_insert) for further details.767///768/// # Examples769///770/// ```rust771/// # use bevy_platform::collections::HashSet;772/// let mut map = HashSet::new();773///774/// assert_eq!(map.get_or_insert("foo"), &"foo");775/// ```776#[inline]777pub fn get_or_insert(&mut self, value: T) -> &T {778self.0.get_or_insert(value)779}780781/// Inserts a value computed from `f` into the set if the given `value` is782/// not present, then returns a reference to the value in the set.783///784/// Refer to [`get_or_insert_with`](hb::HashSet::get_or_insert_with) for further details.785///786/// # Examples787///788/// ```rust789/// # use bevy_platform::collections::HashSet;790/// let mut map = HashSet::new();791///792/// assert_eq!(map.get_or_insert_with(&"foo", |_| "foo"), &"foo");793/// ```794#[inline]795pub fn get_or_insert_with<Q, F>(&mut self, value: &Q, f: F) -> &T796where797Q: Hash + Equivalent<T> + ?Sized,798F: FnOnce(&Q) -> T,799{800self.0.get_or_insert_with(value, f)801}802803/// Gets the given value's corresponding entry in the set for in-place manipulation.804///805/// Refer to [`entry`](hb::HashSet::entry) for further details.806///807/// # Examples808///809/// ```rust810/// # use bevy_platform::collections::HashSet;811/// let mut map = HashSet::new();812///813/// let value = map.entry("foo").or_insert();814/// #815/// # assert_eq!(value, ());816/// ```817#[inline]818pub fn entry(&mut self, value: T) -> Entry<'_, T, S> {819self.0.entry(value)820}821822/// Returns `true` if `self` has no elements in common with `other`.823/// This is equivalent to checking for an empty intersection.824///825/// Refer to [`is_disjoint`](hb::HashSet::is_disjoint) for further details.826#[inline]827pub fn is_disjoint(&self, other: &Self) -> bool {828self.0.is_disjoint(other)829}830831/// Returns `true` if the set is a subset of another,832/// i.e., `other` contains at least all the values in `self`.833///834/// Refer to [`is_subset`](hb::HashSet::is_subset) for further details.835#[inline]836pub fn is_subset(&self, other: &Self) -> bool {837self.0.is_subset(other)838}839840/// Returns `true` if the set is a superset of another,841/// i.e., `self` contains at least all the values in `other`.842///843/// Refer to [`is_superset`](hb::HashSet::is_superset) for further details.844#[inline]845pub fn is_superset(&self, other: &Self) -> bool {846self.0.is_superset(other)847}848849/// Adds a value to the set.850///851/// Refer to [`insert`](hb::HashSet::insert) for further details.852///853/// # Examples854///855/// ```rust856/// # use bevy_platform::collections::HashSet;857/// let mut map = HashSet::new();858///859/// map.insert("foo");860///861/// assert!(map.contains("foo"));862/// ```863#[inline]864pub fn insert(&mut self, value: T) -> bool {865self.0.insert(value)866}867868/// Adds a value to the set, replacing the existing value, if any, that is equal to the given869/// one. Returns the replaced value.870///871/// Refer to [`replace`](hb::HashSet::replace) for further details.872///873/// # Examples874///875/// ```rust876/// # use bevy_platform::collections::HashSet;877/// let mut map = HashSet::new();878///879/// map.insert("foo");880///881/// assert_eq!(map.replace("foo"), Some("foo"));882/// ```883#[inline]884pub fn replace(&mut self, value: T) -> Option<T> {885self.0.replace(value)886}887888/// Removes a value from the set. Returns whether the value was889/// present in the set.890///891/// Refer to [`remove`](hb::HashSet::remove) for further details.892///893/// # Examples894///895/// ```rust896/// # use bevy_platform::collections::HashSet;897/// let mut map = HashSet::new();898///899/// map.insert("foo");900///901/// assert!(map.remove("foo"));902///903/// assert!(map.is_empty());904/// ```905#[inline]906pub fn remove<Q>(&mut self, value: &Q) -> bool907where908Q: Hash + Equivalent<T> + ?Sized,909{910self.0.remove(value)911}912913/// Removes and returns the value in the set, if any, that is equal to the given one.914///915/// Refer to [`take`](hb::HashSet::take) for further details.916///917/// # Examples918///919/// ```rust920/// # use bevy_platform::collections::HashSet;921/// let mut map = HashSet::new();922///923/// map.insert("foo");924///925/// assert_eq!(map.take("foo"), Some("foo"));926///927/// assert!(map.is_empty());928/// ```929#[inline]930pub fn take<Q>(&mut self, value: &Q) -> Option<T>931where932Q: Hash + Equivalent<T> + ?Sized,933{934self.0.take(value)935}936937/// Returns the total amount of memory allocated internally by the hash938/// set, in bytes.939///940/// Refer to [`allocation_size`](hb::HashSet::allocation_size) for further details.941///942/// # Examples943///944/// ```rust945/// # use bevy_platform::collections::HashSet;946/// let mut map = HashSet::new();947///948/// assert_eq!(map.allocation_size(), 0);949///950/// map.insert("foo");951///952/// assert!(map.allocation_size() >= size_of::<&'static str>());953/// ```954#[inline]955pub fn allocation_size(&self) -> usize {956self.0.allocation_size()957}958959/// Insert a value the set without checking if the value already exists in the set.960///961/// Refer to [`insert_unique_unchecked`](hb::HashSet::insert_unique_unchecked) for further details.962///963/// # Safety964///965/// This operation is safe if a value does not exist in the set.966///967/// However, if a value exists in the set already, the behavior is unspecified:968/// this operation may panic, loop forever, or any following operation with the set969/// may panic, loop forever or return arbitrary result.970///971/// That said, this operation (and following operations) are guaranteed to972/// not violate memory safety.973///974/// However this operation is still unsafe because the resulting `HashSet`975/// may be passed to unsafe code which does expect the set to behave976/// correctly, and would cause unsoundness as a result.977#[expect(978unsafe_code,979reason = "re-exporting unsafe method from Hashbrown requires unsafe code"980)]981#[inline]982pub unsafe fn insert_unique_unchecked(&mut self, value: T) -> &T {983// SAFETY: safety contract is ensured by the caller.984unsafe { self.0.insert_unique_unchecked(value) }985}986}987988impl<T, S> BitOr<&HashSet<T, S>> for &HashSet<T, S>989where990for<'a> &'a hb::HashSet<T, S>: BitOr<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,991{992type Output = HashSet<T, S>;993994/// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.995#[inline]996fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {997HashSet(self.0.bitor(&rhs.0))998}999}10001001impl<T, S> BitAnd<&HashSet<T, S>> for &HashSet<T, S>1002where1003for<'a> &'a hb::HashSet<T, S>: BitAnd<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,1004{1005type Output = HashSet<T, S>;10061007/// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.1008#[inline]1009fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {1010HashSet(self.0.bitand(&rhs.0))1011}1012}10131014impl<T, S> BitXor<&HashSet<T, S>> for &HashSet<T, S>1015where1016for<'a> &'a hb::HashSet<T, S>: BitXor<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,1017{1018type Output = HashSet<T, S>;10191020/// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.1021#[inline]1022fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {1023HashSet(self.0.bitxor(&rhs.0))1024}1025}10261027impl<T, S> Sub<&HashSet<T, S>> for &HashSet<T, S>1028where1029for<'a> &'a hb::HashSet<T, S>: Sub<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,1030{1031type Output = HashSet<T, S>;10321033/// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.1034#[inline]1035fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {1036HashSet(self.0.sub(&rhs.0))1037}1038}10391040impl<T, S> BitOrAssign<&HashSet<T, S>> for HashSet<T, S>1041where1042hb::HashSet<T, S>: for<'a> BitOrAssign<&'a hb::HashSet<T, S>>,1043{1044/// Modifies this set to contain the union of `self` and `rhs`.1045#[inline]1046fn bitor_assign(&mut self, rhs: &HashSet<T, S>) {1047self.0.bitor_assign(&rhs.0);1048}1049}10501051impl<T, S> BitAndAssign<&HashSet<T, S>> for HashSet<T, S>1052where1053hb::HashSet<T, S>: for<'a> BitAndAssign<&'a hb::HashSet<T, S>>,1054{1055/// Modifies this set to contain the intersection of `self` and `rhs`.1056#[inline]1057fn bitand_assign(&mut self, rhs: &HashSet<T, S>) {1058self.0.bitand_assign(&rhs.0);1059}1060}10611062impl<T, S> BitXorAssign<&HashSet<T, S>> for HashSet<T, S>1063where1064hb::HashSet<T, S>: for<'a> BitXorAssign<&'a hb::HashSet<T, S>>,1065{1066/// Modifies this set to contain the symmetric difference of `self` and `rhs`.1067#[inline]1068fn bitxor_assign(&mut self, rhs: &HashSet<T, S>) {1069self.0.bitxor_assign(&rhs.0);1070}1071}10721073impl<T, S> SubAssign<&HashSet<T, S>> for HashSet<T, S>1074where1075hb::HashSet<T, S>: for<'a> SubAssign<&'a hb::HashSet<T, S>>,1076{1077/// Modifies this set to contain the difference of `self` and `rhs`.1078#[inline]1079fn sub_assign(&mut self, rhs: &HashSet<T, S>) {1080self.0.sub_assign(&rhs.0);1081}1082}108310841085