Path: blob/main/crates/bevy_platform/src/collections/hash_set.rs
6849 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#[repr(transparent)]37pub struct HashSet<T, S = FixedHasher>(hb::HashSet<T, S>);3839impl<T, S> Clone for HashSet<T, S>40where41hb::HashSet<T, S>: Clone,42{43#[inline]44fn clone(&self) -> Self {45Self(self.0.clone())46}4748#[inline]49fn clone_from(&mut self, source: &Self) {50self.0.clone_from(&source.0);51}52}5354impl<T, S> Debug for HashSet<T, S>55where56hb::HashSet<T, S>: Debug,57{58#[inline]59fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {60<hb::HashSet<T, S> as Debug>::fmt(&self.0, f)61}62}6364impl<T, S> Default for HashSet<T, S>65where66hb::HashSet<T, S>: Default,67{68#[inline]69fn default() -> Self {70Self(Default::default())71}72}7374impl<T, S> PartialEq for HashSet<T, S>75where76hb::HashSet<T, S>: PartialEq,77{78#[inline]79fn eq(&self, other: &Self) -> bool {80self.0.eq(&other.0)81}82}8384impl<T, S> Eq for HashSet<T, S> where hb::HashSet<T, S>: Eq {}8586impl<T, S, X> FromIterator<X> for HashSet<T, S>87where88hb::HashSet<T, S>: FromIterator<X>,89{90#[inline]91fn from_iter<U: IntoIterator<Item = X>>(iter: U) -> Self {92Self(FromIterator::from_iter(iter))93}94}9596impl<T, S> IntoIterator for HashSet<T, S>97where98hb::HashSet<T, S>: IntoIterator,99{100type Item = <hb::HashSet<T, S> as IntoIterator>::Item;101102type IntoIter = <hb::HashSet<T, S> as IntoIterator>::IntoIter;103104#[inline]105fn into_iter(self) -> Self::IntoIter {106self.0.into_iter()107}108}109110impl<'a, T, S> IntoIterator for &'a HashSet<T, S>111where112&'a hb::HashSet<T, S>: IntoIterator,113{114type Item = <&'a hb::HashSet<T, S> as IntoIterator>::Item;115116type IntoIter = <&'a hb::HashSet<T, S> as IntoIterator>::IntoIter;117118#[inline]119fn into_iter(self) -> Self::IntoIter {120(&self.0).into_iter()121}122}123124impl<'a, T, S> IntoIterator for &'a mut HashSet<T, S>125where126&'a mut hb::HashSet<T, S>: IntoIterator,127{128type Item = <&'a mut hb::HashSet<T, S> as IntoIterator>::Item;129130type IntoIter = <&'a mut hb::HashSet<T, S> as IntoIterator>::IntoIter;131132#[inline]133fn into_iter(self) -> Self::IntoIter {134(&mut self.0).into_iter()135}136}137138impl<T, S, X> Extend<X> for HashSet<T, S>139where140hb::HashSet<T, S>: Extend<X>,141{142#[inline]143fn extend<U: IntoIterator<Item = X>>(&mut self, iter: U) {144self.0.extend(iter);145}146}147148impl<T, const N: usize> From<[T; N]> for HashSet<T, FixedHasher>149where150T: Eq + Hash,151{152fn from(value: [T; N]) -> Self {153value.into_iter().collect()154}155}156157impl<T, S> From<crate::collections::HashMap<T, (), S>> for HashSet<T, S> {158#[inline]159fn from(value: crate::collections::HashMap<T, (), S>) -> Self {160Self(hb::HashSet::from(hashbrown::HashMap::from(value)))161}162}163164impl<T, S> From<hb::HashSet<T, S>> for HashSet<T, S> {165#[inline]166fn from(value: hb::HashSet<T, S>) -> Self {167Self(value)168}169}170171impl<T, S> From<HashSet<T, S>> for hb::HashSet<T, S> {172#[inline]173fn from(value: HashSet<T, S>) -> Self {174value.0175}176}177178impl<T, S> Deref for HashSet<T, S> {179type Target = hb::HashSet<T, S>;180181#[inline]182fn deref(&self) -> &Self::Target {183&self.0184}185}186187impl<T, S> DerefMut for HashSet<T, S> {188#[inline]189fn deref_mut(&mut self) -> &mut Self::Target {190&mut self.0191}192}193194#[cfg(feature = "serialize")]195impl<T, S> serde::Serialize for HashSet<T, S>196where197hb::HashSet<T, S>: serde::Serialize,198{199#[inline]200fn serialize<U>(&self, serializer: U) -> Result<U::Ok, U::Error>201where202U: serde::Serializer,203{204self.0.serialize(serializer)205}206}207208#[cfg(feature = "serialize")]209impl<'de, T, S> serde::Deserialize<'de> for HashSet<T, S>210where211hb::HashSet<T, S>: serde::Deserialize<'de>,212{213#[inline]214fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>215where216D: serde::Deserializer<'de>,217{218Ok(Self(serde::Deserialize::deserialize(deserializer)?))219}220}221222#[cfg(feature = "rayon")]223impl<T, S, U> FromParallelIterator<U> for HashSet<T, S>224where225hb::HashSet<T, S>: FromParallelIterator<U>,226U: Send,227{228fn from_par_iter<P>(par_iter: P) -> Self229where230P: IntoParallelIterator<Item = U>,231{232Self(<hb::HashSet<T, S> as FromParallelIterator<U>>::from_par_iter(par_iter))233}234}235236#[cfg(feature = "rayon")]237impl<T, S> IntoParallelIterator for HashSet<T, S>238where239hb::HashSet<T, S>: IntoParallelIterator,240{241type Item = <hb::HashSet<T, S> as IntoParallelIterator>::Item;242type Iter = <hb::HashSet<T, S> as IntoParallelIterator>::Iter;243244fn into_par_iter(self) -> Self::Iter {245self.0.into_par_iter()246}247}248249#[cfg(feature = "rayon")]250impl<'a, T: Sync, S> IntoParallelIterator for &'a HashSet<T, S>251where252&'a hb::HashSet<T, S>: IntoParallelIterator,253{254type Item = <&'a hb::HashSet<T, S> as IntoParallelIterator>::Item;255type Iter = <&'a hb::HashSet<T, S> as IntoParallelIterator>::Iter;256257fn into_par_iter(self) -> Self::Iter {258(&self.0).into_par_iter()259}260}261262#[cfg(feature = "rayon")]263impl<T, S, U> ParallelExtend<U> for HashSet<T, S>264where265hb::HashSet<T, S>: ParallelExtend<U>,266U: Send,267{268fn par_extend<I>(&mut self, par_iter: I)269where270I: IntoParallelIterator<Item = U>,271{272<hb::HashSet<T, S> as ParallelExtend<U>>::par_extend(&mut self.0, par_iter);273}274}275276impl<T> HashSet<T, FixedHasher> {277/// Creates an empty [`HashSet`].278///279/// Refer to [`new`](hb::HashSet::new) for further details.280///281/// # Examples282///283/// ```rust284/// # use bevy_platform::collections::HashSet;285/// #286/// // Creates a HashSet with zero capacity.287/// let map = HashSet::new();288/// #289/// # let mut map = map;290/// # map.insert("foo");291/// # assert_eq!(map.get("foo"), Some("foo").as_ref());292/// ```293#[inline]294pub const fn new() -> Self {295Self::with_hasher(FixedHasher)296}297298/// Creates an empty [`HashSet`] with the specified capacity.299///300/// Refer to [`with_capacity`](hb::HashSet::with_capacity) for further details.301///302/// # Examples303///304/// ```rust305/// # use bevy_platform::collections::HashSet;306/// #307/// // Creates a HashSet with capacity for at least 5 entries.308/// let map = HashSet::with_capacity(5);309/// #310/// # let mut map = map;311/// # map.insert("foo");312/// # assert_eq!(map.get("foo"), Some("foo").as_ref());313/// ```314#[inline]315pub fn with_capacity(capacity: usize) -> Self {316Self::with_capacity_and_hasher(capacity, FixedHasher)317}318}319320impl<T, S> HashSet<T, S> {321/// Returns the number of elements the set can hold without reallocating.322///323/// Refer to [`capacity`](hb::HashSet::capacity) for further details.324///325/// # Examples326///327/// ```rust328/// # use bevy_platform::collections::HashSet;329/// let map = HashSet::with_capacity(5);330///331/// # let map: HashSet<()> = map;332/// #333/// assert!(map.capacity() >= 5);334/// ```335#[inline]336pub fn capacity(&self) -> usize {337self.0.capacity()338}339340/// An iterator visiting all elements in arbitrary order.341/// The iterator element type is `&'a T`.342///343/// Refer to [`iter`](hb::HashSet::iter) for further details.344///345/// # Examples346///347/// ```rust348/// # use bevy_platform::collections::HashSet;349/// #350/// let mut map = HashSet::new();351///352/// map.insert("foo");353/// map.insert("bar");354/// map.insert("baz");355///356/// for value in map.iter() {357/// // "foo", "bar", "baz"358/// // Note that the above order is not guaranteed359/// }360/// #361/// # assert_eq!(map.iter().count(), 3);362/// ```363#[inline]364pub fn iter(&self) -> Iter<'_, T> {365self.0.iter()366}367368/// Returns the number of elements in the set.369///370/// Refer to [`len`](hb::HashSet::len) for further details.371///372/// # Examples373///374/// ```rust375/// # use bevy_platform::collections::HashSet;376/// let mut map = HashSet::new();377///378/// assert_eq!(map.len(), 0);379///380/// map.insert("foo");381///382/// assert_eq!(map.len(), 1);383/// ```384#[inline]385pub fn len(&self) -> usize {386self.0.len()387}388389/// Returns `true` if the set contains no elements.390///391/// Refer to [`is_empty`](hb::HashSet::is_empty) for further details.392///393/// # Examples394///395/// ```rust396/// # use bevy_platform::collections::HashSet;397/// let mut map = HashSet::new();398///399/// assert!(map.is_empty());400///401/// map.insert("foo");402///403/// assert!(!map.is_empty());404/// ```405#[inline]406pub fn is_empty(&self) -> bool {407self.0.is_empty()408}409410/// Clears the set, returning all elements in an iterator.411///412/// Refer to [`drain`](hb::HashSet::drain) for further details.413///414/// # Examples415///416/// ```rust417/// # use bevy_platform::collections::HashSet;418/// #419/// let mut map = HashSet::new();420///421/// map.insert("foo");422/// map.insert("bar");423/// map.insert("baz");424///425/// for value in map.drain() {426/// // "foo", "bar", "baz"427/// // Note that the above order is not guaranteed428/// }429///430/// assert!(map.is_empty());431/// ```432#[inline]433pub fn drain(&mut self) -> Drain<'_, T> {434self.0.drain()435}436437/// Retains only the elements specified by the predicate.438///439/// Refer to [`retain`](hb::HashSet::retain) for further details.440///441/// # Examples442///443/// ```rust444/// # use bevy_platform::collections::HashSet;445/// #446/// let mut map = HashSet::new();447///448/// map.insert("foo");449/// map.insert("bar");450/// map.insert("baz");451///452/// map.retain(|value| *value == "baz");453///454/// assert_eq!(map.len(), 1);455/// ```456#[inline]457pub fn retain<F>(&mut self, f: F)458where459F: FnMut(&T) -> bool,460{461self.0.retain(f);462}463464/// Drains elements which are true under the given predicate,465/// and returns an iterator over the removed items.466///467/// Refer to [`extract_if`](hb::HashSet::extract_if) for further details.468///469/// # Examples470///471/// ```rust472/// # use bevy_platform::collections::HashSet;473/// #474/// let mut map = HashSet::new();475///476/// map.insert("foo");477/// map.insert("bar");478/// map.insert("baz");479///480/// let extracted = map481/// .extract_if(|value| *value == "baz")482/// .collect::<Vec<_>>();483///484/// assert_eq!(map.len(), 2);485/// assert_eq!(extracted.len(), 1);486/// ```487#[inline]488pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, T, F>489where490F: FnMut(&T) -> bool,491{492self.0.extract_if(f)493}494495/// Clears the set, removing all values.496///497/// Refer to [`clear`](hb::HashSet::clear) for further details.498///499/// # Examples500///501/// ```rust502/// # use bevy_platform::collections::HashSet;503/// #504/// let mut map = HashSet::new();505///506/// map.insert("foo");507/// map.insert("bar");508/// map.insert("baz");509///510/// map.clear();511///512/// assert!(map.is_empty());513/// ```514#[inline]515pub fn clear(&mut self) {516self.0.clear();517}518519/// Creates a new empty hash set which will use the given hasher to hash520/// keys.521///522/// Refer to [`with_hasher`](hb::HashSet::with_hasher) for further details.523///524/// # Examples525///526/// ```rust527/// # use bevy_platform::collections::HashSet;528/// # use bevy_platform::hash::FixedHasher as SomeHasher;529/// // Creates a HashSet with the provided hasher.530/// let map = HashSet::with_hasher(SomeHasher);531/// #532/// # let mut map = map;533/// # map.insert("foo");534/// # assert_eq!(map.get("foo"), Some("foo").as_ref());535/// ```536#[inline]537pub const fn with_hasher(hasher: S) -> Self {538Self(hb::HashSet::with_hasher(hasher))539}540541/// Creates an empty [`HashSet`] with the specified capacity, using542/// `hasher` to hash the keys.543///544/// Refer to [`with_capacity_and_hasher`](hb::HashSet::with_capacity_and_hasher) for further details.545///546/// # Examples547///548/// ```rust549/// # use bevy_platform::collections::HashSet;550/// # use bevy_platform::hash::FixedHasher as SomeHasher;551/// // Creates a HashSet with capacity for 5 entries and the provided hasher.552/// let map = HashSet::with_capacity_and_hasher(5, SomeHasher);553/// #554/// # let mut map = map;555/// # map.insert("foo");556/// # assert_eq!(map.get("foo"), Some("foo").as_ref());557/// ```558#[inline]559pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {560Self(hb::HashSet::with_capacity_and_hasher(capacity, hasher))561}562563/// Returns a reference to the set's [`BuildHasher`].564///565/// Refer to [`hasher`](hb::HashSet::hasher) for further details.566#[inline]567pub fn hasher(&self) -> &S {568self.0.hasher()569}570571/// Takes the inner [`HashSet`](hb::HashSet) out of this wrapper.572///573/// # Examples574///575/// ```rust576/// # use bevy_platform::collections::HashSet;577/// let map: HashSet<&'static str> = HashSet::new();578/// let map: hashbrown::HashSet<&'static str, _> = map.into_inner();579/// ```580#[inline]581pub fn into_inner(self) -> hb::HashSet<T, S> {582self.0583}584}585586impl<T, S> HashSet<T, S>587where588T: Eq + Hash,589S: BuildHasher,590{591/// Reserves capacity for at least `additional` more elements to be inserted592/// in the [`HashSet`]. The collection may reserve more space to avoid593/// frequent reallocations.594///595/// Refer to [`reserve`](hb::HashSet::reserve) for further details.596///597/// # Examples598///599/// ```rust600/// # use bevy_platform::collections::HashSet;601/// let mut map = HashSet::with_capacity(5);602///603/// # let mut map: HashSet<()> = map;604/// #605/// assert!(map.capacity() >= 5);606///607/// map.reserve(10);608///609/// assert!(map.capacity() - map.len() >= 10);610/// ```611#[inline]612pub fn reserve(&mut self, additional: usize) {613self.0.reserve(additional);614}615616/// Tries to reserve capacity for at least `additional` more elements to be inserted617/// in the given `HashSet<K,V>`. The collection may reserve more space to avoid618/// frequent reallocations.619///620/// Refer to [`try_reserve`](hb::HashSet::try_reserve) for further details.621///622/// # Examples623///624/// ```rust625/// # use bevy_platform::collections::HashSet;626/// let mut map = HashSet::with_capacity(5);627///628/// # let mut map: HashSet<()> = map;629/// #630/// assert!(map.capacity() >= 5);631///632/// map.try_reserve(10).expect("Out of Memory!");633///634/// assert!(map.capacity() - map.len() >= 10);635/// ```636#[inline]637pub fn try_reserve(&mut self, additional: usize) -> Result<(), hashbrown::TryReserveError> {638self.0.try_reserve(additional)639}640641/// Shrinks the capacity of the set as much as possible. It will drop642/// down as much as possible while maintaining the internal rules643/// and possibly leaving some space in accordance with the resize policy.644///645/// Refer to [`shrink_to_fit`](hb::HashSet::shrink_to_fit) for further details.646///647/// # Examples648///649/// ```rust650/// # use bevy_platform::collections::HashSet;651/// let mut map = HashSet::with_capacity(5);652///653/// map.insert("foo");654/// map.insert("bar");655/// map.insert("baz");656///657/// assert!(map.capacity() >= 5);658///659/// map.shrink_to_fit();660///661/// assert_eq!(map.capacity(), 3);662/// ```663#[inline]664pub fn shrink_to_fit(&mut self) {665self.0.shrink_to_fit();666}667668/// Shrinks the capacity of the set with a lower limit. It will drop669/// down no lower than the supplied limit while maintaining the internal rules670/// and possibly leaving some space in accordance with the resize policy.671///672/// Refer to [`shrink_to`](hb::HashSet::shrink_to) for further details.673#[inline]674pub fn shrink_to(&mut self, min_capacity: usize) {675self.0.shrink_to(min_capacity);676}677678/// Visits the values representing the difference,679/// i.e., the values that are in `self` but not in `other`.680///681/// Refer to [`difference`](hb::HashSet::difference) for further details.682#[inline]683pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, T, S> {684self.0.difference(other)685}686687/// Visits the values representing the symmetric difference,688/// i.e., the values that are in `self` or in `other` but not in both.689///690/// Refer to [`symmetric_difference`](hb::HashSet::symmetric_difference) for further details.691#[inline]692pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, T, S> {693self.0.symmetric_difference(other)694}695696/// Visits the values representing the intersection,697/// i.e., the values that are both in `self` and `other`.698///699/// Refer to [`intersection`](hb::HashSet::intersection) for further details.700#[inline]701pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T, S> {702self.0.intersection(other)703}704705/// Visits the values representing the union,706/// i.e., all the values in `self` or `other`, without duplicates.707///708/// Refer to [`union`](hb::HashSet::union) for further details.709#[inline]710pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T, S> {711self.0.union(other)712}713714/// Returns `true` if the set contains a value.715///716/// Refer to [`contains`](hb::HashSet::contains) for further details.717///718/// # Examples719///720/// ```rust721/// # use bevy_platform::collections::HashSet;722/// let mut map = HashSet::new();723///724/// map.insert("foo");725///726/// assert!(map.contains("foo"));727/// ```728#[inline]729pub fn contains<Q>(&self, value: &Q) -> bool730where731Q: Hash + Equivalent<T> + ?Sized,732{733self.0.contains(value)734}735736/// Returns a reference to the value in the set, if any, that is equal to the given value.737///738/// Refer to [`get`](hb::HashSet::get) for further details.739///740/// # Examples741///742/// ```rust743/// # use bevy_platform::collections::HashSet;744/// let mut map = HashSet::new();745///746/// map.insert("foo");747///748/// assert_eq!(map.get("foo"), Some(&"foo"));749/// ```750#[inline]751pub fn get<Q>(&self, value: &Q) -> Option<&T>752where753Q: Hash + Equivalent<T> + ?Sized,754{755self.0.get(value)756}757758/// Inserts the given `value` into the set if it is not present, then759/// returns a reference to the value in the set.760///761/// Refer to [`get_or_insert`](hb::HashSet::get_or_insert) for further details.762///763/// # Examples764///765/// ```rust766/// # use bevy_platform::collections::HashSet;767/// let mut map = HashSet::new();768///769/// assert_eq!(map.get_or_insert("foo"), &"foo");770/// ```771#[inline]772pub fn get_or_insert(&mut self, value: T) -> &T {773self.0.get_or_insert(value)774}775776/// Inserts a value computed from `f` into the set if the given `value` is777/// not present, then returns a reference to the value in the set.778///779/// Refer to [`get_or_insert_with`](hb::HashSet::get_or_insert_with) for further details.780///781/// # Examples782///783/// ```rust784/// # use bevy_platform::collections::HashSet;785/// let mut map = HashSet::new();786///787/// assert_eq!(map.get_or_insert_with(&"foo", |_| "foo"), &"foo");788/// ```789#[inline]790pub fn get_or_insert_with<Q, F>(&mut self, value: &Q, f: F) -> &T791where792Q: Hash + Equivalent<T> + ?Sized,793F: FnOnce(&Q) -> T,794{795self.0.get_or_insert_with(value, f)796}797798/// Gets the given value's corresponding entry in the set for in-place manipulation.799///800/// Refer to [`entry`](hb::HashSet::entry) for further details.801///802/// # Examples803///804/// ```rust805/// # use bevy_platform::collections::HashSet;806/// let mut map = HashSet::new();807///808/// let value = map.entry("foo").or_insert();809/// #810/// # assert_eq!(value, ());811/// ```812#[inline]813pub fn entry(&mut self, value: T) -> Entry<'_, T, S> {814self.0.entry(value)815}816817/// Returns `true` if `self` has no elements in common with `other`.818/// This is equivalent to checking for an empty intersection.819///820/// Refer to [`is_disjoint`](hb::HashSet::is_disjoint) for further details.821#[inline]822pub fn is_disjoint(&self, other: &Self) -> bool {823self.0.is_disjoint(other)824}825826/// Returns `true` if the set is a subset of another,827/// i.e., `other` contains at least all the values in `self`.828///829/// Refer to [`is_subset`](hb::HashSet::is_subset) for further details.830#[inline]831pub fn is_subset(&self, other: &Self) -> bool {832self.0.is_subset(other)833}834835/// Returns `true` if the set is a superset of another,836/// i.e., `self` contains at least all the values in `other`.837///838/// Refer to [`is_superset`](hb::HashSet::is_superset) for further details.839#[inline]840pub fn is_superset(&self, other: &Self) -> bool {841self.0.is_superset(other)842}843844/// Adds a value to the set.845///846/// Refer to [`insert`](hb::HashSet::insert) for further details.847///848/// # Examples849///850/// ```rust851/// # use bevy_platform::collections::HashSet;852/// let mut map = HashSet::new();853///854/// map.insert("foo");855///856/// assert!(map.contains("foo"));857/// ```858#[inline]859pub fn insert(&mut self, value: T) -> bool {860self.0.insert(value)861}862863/// Adds a value to the set, replacing the existing value, if any, that is equal to the given864/// one. Returns the replaced value.865///866/// Refer to [`replace`](hb::HashSet::replace) for further details.867///868/// # Examples869///870/// ```rust871/// # use bevy_platform::collections::HashSet;872/// let mut map = HashSet::new();873///874/// map.insert("foo");875///876/// assert_eq!(map.replace("foo"), Some("foo"));877/// ```878#[inline]879pub fn replace(&mut self, value: T) -> Option<T> {880self.0.replace(value)881}882883/// Removes a value from the set. Returns whether the value was884/// present in the set.885///886/// Refer to [`remove`](hb::HashSet::remove) for further details.887///888/// # Examples889///890/// ```rust891/// # use bevy_platform::collections::HashSet;892/// let mut map = HashSet::new();893///894/// map.insert("foo");895///896/// assert!(map.remove("foo"));897///898/// assert!(map.is_empty());899/// ```900#[inline]901pub fn remove<Q>(&mut self, value: &Q) -> bool902where903Q: Hash + Equivalent<T> + ?Sized,904{905self.0.remove(value)906}907908/// Removes and returns the value in the set, if any, that is equal to the given one.909///910/// Refer to [`take`](hb::HashSet::take) for further details.911///912/// # Examples913///914/// ```rust915/// # use bevy_platform::collections::HashSet;916/// let mut map = HashSet::new();917///918/// map.insert("foo");919///920/// assert_eq!(map.take("foo"), Some("foo"));921///922/// assert!(map.is_empty());923/// ```924#[inline]925pub fn take<Q>(&mut self, value: &Q) -> Option<T>926where927Q: Hash + Equivalent<T> + ?Sized,928{929self.0.take(value)930}931932/// Returns the total amount of memory allocated internally by the hash933/// set, in bytes.934///935/// Refer to [`allocation_size`](hb::HashSet::allocation_size) for further details.936///937/// # Examples938///939/// ```rust940/// # use bevy_platform::collections::HashSet;941/// let mut map = HashSet::new();942///943/// assert_eq!(map.allocation_size(), 0);944///945/// map.insert("foo");946///947/// assert!(map.allocation_size() >= size_of::<&'static str>());948/// ```949#[inline]950pub fn allocation_size(&self) -> usize {951self.0.allocation_size()952}953954/// Insert a value the set without checking if the value already exists in the set.955///956/// Refer to [`insert_unique_unchecked`](hb::HashSet::insert_unique_unchecked) for further details.957///958/// # Safety959///960/// This operation is safe if a value does not exist in the set.961///962/// However, if a value exists in the set already, the behavior is unspecified:963/// this operation may panic, loop forever, or any following operation with the set964/// may panic, loop forever or return arbitrary result.965///966/// That said, this operation (and following operations) are guaranteed to967/// not violate memory safety.968///969/// However this operation is still unsafe because the resulting `HashSet`970/// may be passed to unsafe code which does expect the set to behave971/// correctly, and would cause unsoundness as a result.972#[expect(973unsafe_code,974reason = "re-exporting unsafe method from Hashbrown requires unsafe code"975)]976#[inline]977pub unsafe fn insert_unique_unchecked(&mut self, value: T) -> &T {978// SAFETY: safety contract is ensured by the caller.979unsafe { self.0.insert_unique_unchecked(value) }980}981}982983impl<T, S> BitOr<&HashSet<T, S>> for &HashSet<T, S>984where985for<'a> &'a hb::HashSet<T, S>: BitOr<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,986{987type Output = HashSet<T, S>;988989/// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.990#[inline]991fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {992HashSet(self.0.bitor(&rhs.0))993}994}995996impl<T, S> BitAnd<&HashSet<T, S>> for &HashSet<T, S>997where998for<'a> &'a hb::HashSet<T, S>: BitAnd<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,999{1000type Output = HashSet<T, S>;10011002/// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.1003#[inline]1004fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {1005HashSet(self.0.bitand(&rhs.0))1006}1007}10081009impl<T, S> BitXor<&HashSet<T, S>> for &HashSet<T, S>1010where1011for<'a> &'a hb::HashSet<T, S>: BitXor<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,1012{1013type Output = HashSet<T, S>;10141015/// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.1016#[inline]1017fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {1018HashSet(self.0.bitxor(&rhs.0))1019}1020}10211022impl<T, S> Sub<&HashSet<T, S>> for &HashSet<T, S>1023where1024for<'a> &'a hb::HashSet<T, S>: Sub<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,1025{1026type Output = HashSet<T, S>;10271028/// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.1029#[inline]1030fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {1031HashSet(self.0.sub(&rhs.0))1032}1033}10341035impl<T, S> BitOrAssign<&HashSet<T, S>> for HashSet<T, S>1036where1037hb::HashSet<T, S>: for<'a> BitOrAssign<&'a hb::HashSet<T, S>>,1038{1039/// Modifies this set to contain the union of `self` and `rhs`.1040#[inline]1041fn bitor_assign(&mut self, rhs: &HashSet<T, S>) {1042self.0.bitor_assign(&rhs.0);1043}1044}10451046impl<T, S> BitAndAssign<&HashSet<T, S>> for HashSet<T, S>1047where1048hb::HashSet<T, S>: for<'a> BitAndAssign<&'a hb::HashSet<T, S>>,1049{1050/// Modifies this set to contain the intersection of `self` and `rhs`.1051#[inline]1052fn bitand_assign(&mut self, rhs: &HashSet<T, S>) {1053self.0.bitand_assign(&rhs.0);1054}1055}10561057impl<T, S> BitXorAssign<&HashSet<T, S>> for HashSet<T, S>1058where1059hb::HashSet<T, S>: for<'a> BitXorAssign<&'a hb::HashSet<T, S>>,1060{1061/// Modifies this set to contain the symmetric difference of `self` and `rhs`.1062#[inline]1063fn bitxor_assign(&mut self, rhs: &HashSet<T, S>) {1064self.0.bitxor_assign(&rhs.0);1065}1066}10671068impl<T, S> SubAssign<&HashSet<T, S>> for HashSet<T, S>1069where1070hb::HashSet<T, S>: for<'a> SubAssign<&'a hb::HashSet<T, S>>,1071{1072/// Modifies this set to contain the difference of `self` and `rhs`.1073#[inline]1074fn sub_assign(&mut self, rhs: &HashSet<T, S>) {1075self.0.sub_assign(&rhs.0);1076}1077}107810791080