diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 482d57b47f677..5e81d901ef601 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -4,6 +4,7 @@ mod tests; use hashbrown::hash_set as base; use super::map::map_try_reserve_error; +use crate::alloc::{Allocator, Global}; use crate::borrow::Borrow; use crate::collections::TryReserveError; use crate::fmt; @@ -122,8 +123,12 @@ use crate::ops::{BitAnd, BitOr, BitXor, Sub}; /// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "HashSet")] #[stable(feature = "rust1", since = "1.0.0")] -pub struct HashSet { - base: base::HashSet, +pub struct HashSet< + T, + S = RandomState, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::HashSet, } impl HashSet { @@ -166,7 +171,141 @@ impl HashSet { } } +impl HashSet { + /// Creates an empty `HashSet` in the provided allocator. + /// + /// The hash set is initially created with a capacity of 0, so it will not allocate until it + /// is first inserted into. + #[inline] + #[must_use] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn new_in(alloc: A) -> HashSet { + HashSet::with_hasher_in(Default::default(), alloc) + } + + /// Creates an empty `HashSet` with at least the specified capacity. + /// + /// The hash set will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is zero, the hash set will not allocate. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// let set: HashSet = HashSet::with_capacity(10); + /// assert!(set.capacity() >= 10); + /// ``` + #[inline] + #[must_use] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn with_capacity_in(capacity: usize, alloc: A) -> HashSet { + HashSet::with_capacity_and_hasher_in(capacity, Default::default(), alloc) + } +} + impl HashSet { + /// Creates a new empty hash set which will use the given hasher to hash + /// keys. + /// + /// The hash set is also created with the default initial capacity. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow `HashSet`s to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// The `hash_builder` passed should implement the [`BuildHasher`] trait for + /// the `HashSet` to be useful, see its documentation for details. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// use std::hash::RandomState; + /// + /// let s = RandomState::new(); + /// let mut set = HashSet::with_hasher(s); + /// set.insert(2); + /// ``` + #[inline] + #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] + #[rustc_const_stable(feature = "const_collections_with_hasher", since = "1.85.0")] + pub const fn with_hasher(hasher: S) -> HashSet { + HashSet { base: base::HashSet::with_hasher(hasher) } + } + + /// Creates an empty `HashSet` with at least the specified capacity, using + /// `hasher` to hash the keys. + /// + /// The hash set will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is zero, the hash set will not allocate. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow `HashSet`s to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// The `hash_builder` passed should implement the [`BuildHasher`] trait for + /// the `HashSet` to be useful, see its documentation for details. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// use std::hash::RandomState; + /// + /// let s = RandomState::new(); + /// let mut set = HashSet::with_capacity_and_hasher(10, s); + /// set.insert(1); + /// ``` + #[inline] + #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] + pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet { + HashSet { base: base::HashSet::with_capacity_and_hasher(capacity, hasher) } + } +} + +impl HashSet { + /// Creates a new empty hash set which will use the given hasher to hash + /// keys and will allocate memory using the provided allocator. + /// + /// The hash set is also created with the default initial capacity. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow `HashSet`s to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// The `hash_builder` passed should implement the [`BuildHasher`] trait for + /// the `HashSet` to be useful, see its documentation for details. + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn with_hasher_in(hasher: S, alloc: A) -> HashSet { + HashSet { base: base::HashSet::with_hasher_in(hasher, alloc) } + } + + /// Creates an empty `HashSet` with at least the specified capacity, using + /// `hasher` to hash the keys and `alloc` to allocate memory. + /// + /// The hash set will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is zero, the hash set will not allocate. + /// + /// Warning: `hasher` is normally randomly generated, and + /// is designed to allow `HashSet`s to be resistant to attacks that + /// cause many collisions and very poor performance. Setting it + /// manually using this function can expose a DoS attack vector. + /// + /// The `hash_builder` passed should implement the [`BuildHasher`] trait for + /// the `HashSet` to be useful, see its documentation for details. + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn with_capacity_and_hasher_in(capacity: usize, hasher: S, alloc: A) -> HashSet { + HashSet { base: base::HashSet::with_capacity_and_hasher_in(capacity, hasher, alloc) } + } + /// Returns the number of elements the set can hold without reallocating. /// /// # Examples @@ -272,7 +411,7 @@ impl HashSet { #[inline] #[rustc_lint_query_instability] #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self) -> Drain<'_, T> { + pub fn drain(&mut self) -> Drain<'_, T, A> { Drain { base: self.base.drain() } } @@ -309,7 +448,7 @@ impl HashSet { #[inline] #[rustc_lint_query_instability] #[stable(feature = "hash_extract_if", since = "1.88.0")] - pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, T, F> + pub fn extract_if(&mut self, pred: F) -> ExtractIf<'_, T, F, A> where F: FnMut(&T) -> bool, { @@ -362,67 +501,6 @@ impl HashSet { self.base.clear() } - /// Creates a new empty hash set which will use the given hasher to hash - /// keys. - /// - /// The hash set is also created with the default initial capacity. - /// - /// Warning: `hasher` is normally randomly generated, and - /// is designed to allow `HashSet`s to be resistant to attacks that - /// cause many collisions and very poor performance. Setting it - /// manually using this function can expose a DoS attack vector. - /// - /// The `hash_builder` passed should implement the [`BuildHasher`] trait for - /// the `HashSet` to be useful, see its documentation for details. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashSet; - /// use std::hash::RandomState; - /// - /// let s = RandomState::new(); - /// let mut set = HashSet::with_hasher(s); - /// set.insert(2); - /// ``` - #[inline] - #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - #[rustc_const_stable(feature = "const_collections_with_hasher", since = "1.85.0")] - pub const fn with_hasher(hasher: S) -> HashSet { - HashSet { base: base::HashSet::with_hasher(hasher) } - } - - /// Creates an empty `HashSet` with at least the specified capacity, using - /// `hasher` to hash the keys. - /// - /// The hash set will be able to hold at least `capacity` elements without - /// reallocating. This method is allowed to allocate for more elements than - /// `capacity`. If `capacity` is zero, the hash set will not allocate. - /// - /// Warning: `hasher` is normally randomly generated, and - /// is designed to allow `HashSet`s to be resistant to attacks that - /// cause many collisions and very poor performance. Setting it - /// manually using this function can expose a DoS attack vector. - /// - /// The `hash_builder` passed should implement the [`BuildHasher`] trait for - /// the `HashSet` to be useful, see its documentation for details. - /// - /// # Examples - /// - /// ``` - /// use std::collections::HashSet; - /// use std::hash::RandomState; - /// - /// let s = RandomState::new(); - /// let mut set = HashSet::with_capacity_and_hasher(10, s); - /// set.insert(1); - /// ``` - #[inline] - #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet { - HashSet { base: base::HashSet::with_capacity_and_hasher(capacity, hasher) } - } - /// Returns a reference to the set's [`BuildHasher`]. /// /// # Examples @@ -442,10 +520,11 @@ impl HashSet { } } -impl HashSet +impl HashSet where T: Eq + Hash, S: BuildHasher, + A: Allocator, { /// Reserves capacity for at least `additional` more elements to be inserted /// in the `HashSet`. The collection may reserve more space to speculatively @@ -569,7 +648,7 @@ where #[inline] #[rustc_lint_query_instability] #[stable(feature = "rust1", since = "1.0.0")] - pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, S> { + pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, S, A> { Difference { iter: self.iter(), other } } @@ -599,8 +678,8 @@ where #[stable(feature = "rust1", since = "1.0.0")] pub fn symmetric_difference<'a>( &'a self, - other: &'a HashSet, - ) -> SymmetricDifference<'a, T, S> { + other: &'a HashSet, + ) -> SymmetricDifference<'a, T, S, A> { SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } } @@ -631,7 +710,7 @@ where #[inline] #[rustc_lint_query_instability] #[stable(feature = "rust1", since = "1.0.0")] - pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S> { + pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S, A> { if self.len() <= other.len() { Intersection { iter: self.iter(), other } } else { @@ -660,7 +739,7 @@ where #[inline] #[rustc_lint_query_instability] #[stable(feature = "rust1", since = "1.0.0")] - pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S> { + pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, S, A> { if self.len() >= other.len() { Union { iter: self.iter().chain(other.difference(self)) } } else { @@ -812,7 +891,7 @@ where /// ``` #[inline] #[unstable(feature = "hash_set_entry", issue = "60896")] - pub fn entry(&mut self, value: T) -> Entry<'_, T, S> { + pub fn entry(&mut self, value: T) -> Entry<'_, T, S, A> { map_entry(self.base.entry(value)) } @@ -834,7 +913,7 @@ where /// assert_eq!(a.is_disjoint(&b), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_disjoint(&self, other: &HashSet) -> bool { + pub fn is_disjoint(&self, other: &HashSet) -> bool { if self.len() <= other.len() { self.iter().all(|v| !other.contains(v)) } else { @@ -860,7 +939,7 @@ where /// assert_eq!(set.is_subset(&sup), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_subset(&self, other: &HashSet) -> bool { + pub fn is_subset(&self, other: &HashSet) -> bool { if self.len() <= other.len() { self.iter().all(|v| other.contains(v)) } else { false } } @@ -886,7 +965,7 @@ where /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_superset(&self, other: &HashSet) -> bool { + pub fn is_superset(&self, other: &HashSet) -> bool { other.is_subset(self) } @@ -995,7 +1074,7 @@ where } #[inline] -fn map_entry<'a, K: 'a, V: 'a>(raw: base::Entry<'a, K, V>) -> Entry<'a, K, V> { +fn map_entry<'a, K: 'a, V: 'a, A: Allocator>(raw: base::Entry<'a, K, V, A>) -> Entry<'a, K, V, A> { match raw { base::Entry::Occupied(base) => Entry::Occupied(OccupiedEntry { base }), base::Entry::Vacant(base) => Entry::Vacant(VacantEntry { base }), @@ -1003,10 +1082,11 @@ fn map_entry<'a, K: 'a, V: 'a>(raw: base::Entry<'a, K, V>) -> Entry<'a, K, V> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for HashSet +impl Clone for HashSet where T: Clone, S: Clone, + A: Allocator + Clone, { #[inline] fn clone(&self) -> Self { @@ -1024,12 +1104,13 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for HashSet +impl PartialEq for HashSet where T: Eq + Hash, S: BuildHasher, + A: Allocator, { - fn eq(&self, other: &HashSet) -> bool { + fn eq(&self, other: &HashSet) -> bool { if self.len() != other.len() { return false; } @@ -1039,17 +1120,19 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for HashSet +impl Eq for HashSet where T: Eq + Hash, S: BuildHasher, + A: Allocator, { } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for HashSet +impl fmt::Debug for HashSet where T: fmt::Debug, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_set().entries(self.iter()).finish() @@ -1107,10 +1190,11 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for HashSet +impl Extend for HashSet where T: Eq + Hash, S: BuildHasher, + A: Allocator, { #[inline] fn extend>(&mut self, iter: I) { @@ -1129,10 +1213,11 @@ where } #[stable(feature = "hash_extend_copy", since = "1.4.0")] -impl<'a, T, S> Extend<&'a T> for HashSet +impl<'a, T, S, A> Extend<&'a T> for HashSet where T: 'a + Eq + Hash + Copy, S: BuildHasher, + A: Allocator, { #[inline] fn extend>(&mut self, iter: I) { @@ -1341,8 +1426,11 @@ impl Default for Iter<'_, K> { /// let mut iter = a.into_iter(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub struct IntoIter { - base: base::IntoIter, +pub struct IntoIter< + K, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::IntoIter, } #[stable(feature = "default_iters_hash", since = "1.83.0")] @@ -1371,8 +1459,12 @@ impl Default for IntoIter { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "hashset_drain_ty")] -pub struct Drain<'a, K: 'a> { - base: base::Drain<'a, K>, +pub struct Drain< + 'a, + K: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::Drain<'a, K, A>, } /// A draining, filtering iterator over the items of a `HashSet`. @@ -1391,8 +1483,13 @@ pub struct Drain<'a, K: 'a> { /// let mut extract_ifed = a.extract_if(|v| v % 2 == 0); /// ``` #[stable(feature = "hash_extract_if", since = "1.88.0")] -pub struct ExtractIf<'a, K, F> { - base: base::ExtractIf<'a, K, F>, +pub struct ExtractIf< + 'a, + K, + F, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::ExtractIf<'a, K, F, A>, } /// A lazy iterator producing elements in the intersection of `HashSet`s. @@ -1415,11 +1512,16 @@ pub struct ExtractIf<'a, K, F> { #[must_use = "this returns the intersection as an iterator, \ without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Intersection<'a, T: 'a, S: 'a> { +pub struct Intersection< + 'a, + T: 'a, + S: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { // iterator of the first set iter: Iter<'a, T>, // the second set - other: &'a HashSet, + other: &'a HashSet, } /// A lazy iterator producing elements in the difference of `HashSet`s. @@ -1442,11 +1544,16 @@ pub struct Intersection<'a, T: 'a, S: 'a> { #[must_use = "this returns the difference as an iterator, \ without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Difference<'a, T: 'a, S: 'a> { +pub struct Difference< + 'a, + T: 'a, + S: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { // iterator of the first set iter: Iter<'a, T>, // the second set - other: &'a HashSet, + other: &'a HashSet, } /// A lazy iterator producing elements in the symmetric difference of `HashSet`s. @@ -1469,8 +1576,13 @@ pub struct Difference<'a, T: 'a, S: 'a> { #[must_use = "this returns the difference as an iterator, \ without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct SymmetricDifference<'a, T: 'a, S: 'a> { - iter: Chain, Difference<'a, T, S>>, +pub struct SymmetricDifference< + 'a, + T: 'a, + S: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + iter: Chain, Difference<'a, T, S, A>>, } /// A lazy iterator producing elements in the union of `HashSet`s. @@ -1493,12 +1605,17 @@ pub struct SymmetricDifference<'a, T: 'a, S: 'a> { #[must_use = "this returns the union as an iterator, \ without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Union<'a, T: 'a, S: 'a> { - iter: Chain, Difference<'a, T, S>>, +pub struct Union< + 'a, + T: 'a, + S: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + iter: Chain, Difference<'a, T, S, A>>, } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S> IntoIterator for &'a HashSet { +impl<'a, T, S, A: Allocator> IntoIterator for &'a HashSet { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -1510,9 +1627,9 @@ impl<'a, T, S> IntoIterator for &'a HashSet { } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for HashSet { +impl IntoIterator for HashSet { type Item = T; - type IntoIter = IntoIter; + type IntoIter = IntoIter; /// Creates a consuming iterator, that is, one that moves each value out /// of the set in arbitrary order. The set cannot be used after calling @@ -1536,7 +1653,7 @@ impl IntoIterator for HashSet { /// ``` #[inline] #[rustc_lint_query_instability] - fn into_iter(self) -> IntoIter { + fn into_iter(self) -> IntoIter { IntoIter { base: self.base.into_iter() } } } @@ -1591,7 +1708,7 @@ impl fmt::Debug for Iter<'_, K> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = K; #[inline] @@ -1616,24 +1733,24 @@ impl Iterator for IntoIter { } } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for IntoIter { +impl ExactSizeIterator for IntoIter { #[inline] fn len(&self) -> usize { self.base.len() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for IntoIter {} +impl FusedIterator for IntoIter {} #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for IntoIter { +impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.base, f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, K> Iterator for Drain<'a, K> { +impl<'a, K, A: Allocator> Iterator for Drain<'a, K, A> { type Item = K; #[inline] @@ -1654,24 +1771,24 @@ impl<'a, K> Iterator for Drain<'a, K> { } } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Drain<'_, K> { +impl ExactSizeIterator for Drain<'_, K, A> { #[inline] fn len(&self) -> usize { self.base.len() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Drain<'_, K> {} +impl FusedIterator for Drain<'_, K, A> {} #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Drain<'_, K> { +impl fmt::Debug for Drain<'_, K, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.base, f) } } #[stable(feature = "hash_extract_if", since = "1.88.0")] -impl Iterator for ExtractIf<'_, K, F> +impl Iterator for ExtractIf<'_, K, F, A> where F: FnMut(&K) -> bool, { @@ -1688,10 +1805,10 @@ where } #[stable(feature = "hash_extract_if", since = "1.88.0")] -impl FusedIterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool {} +impl FusedIterator for ExtractIf<'_, K, F, A> where F: FnMut(&K) -> bool {} #[stable(feature = "hash_extract_if", since = "1.88.0")] -impl fmt::Debug for ExtractIf<'_, K, F> +impl fmt::Debug for ExtractIf<'_, K, F, A> where K: fmt::Debug, { @@ -1701,7 +1818,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Intersection<'_, T, S> { +impl Clone for Intersection<'_, T, S, A> { #[inline] fn clone(&self) -> Self { Intersection { iter: self.iter.clone(), ..*self } @@ -1709,10 +1826,11 @@ impl Clone for Intersection<'_, T, S> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S> Iterator for Intersection<'a, T, S> +impl<'a, T, S, A> Iterator for Intersection<'a, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { type Item = &'a T; @@ -1743,10 +1861,11 @@ where } #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Intersection<'_, T, S> +impl fmt::Debug for Intersection<'_, T, S, A> where T: fmt::Debug + Eq + Hash, S: BuildHasher, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1754,15 +1873,16 @@ where } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Intersection<'_, T, S> +impl FusedIterator for Intersection<'_, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Difference<'_, T, S> { +impl Clone for Difference<'_, T, S, A> { #[inline] fn clone(&self) -> Self { Difference { iter: self.iter.clone(), ..*self } @@ -1770,10 +1890,11 @@ impl Clone for Difference<'_, T, S> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S> Iterator for Difference<'a, T, S> +impl<'a, T, S, A> Iterator for Difference<'a, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { type Item = &'a T; @@ -1804,18 +1925,20 @@ where } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Difference<'_, T, S> +impl FusedIterator for Difference<'_, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { } #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Difference<'_, T, S> +impl fmt::Debug for Difference<'_, T, S, A> where T: fmt::Debug + Eq + Hash, S: BuildHasher, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1823,7 +1946,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for SymmetricDifference<'_, T, S> { +impl Clone for SymmetricDifference<'_, T, S, A> { #[inline] fn clone(&self) -> Self { SymmetricDifference { iter: self.iter.clone() } @@ -1831,10 +1954,11 @@ impl Clone for SymmetricDifference<'_, T, S> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S> +impl<'a, T, S, A> Iterator for SymmetricDifference<'a, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { type Item = &'a T; @@ -1857,18 +1981,20 @@ where } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for SymmetricDifference<'_, T, S> +impl FusedIterator for SymmetricDifference<'_, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { } #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for SymmetricDifference<'_, T, S> +impl fmt::Debug for SymmetricDifference<'_, T, S, A> where T: fmt::Debug + Eq + Hash, S: BuildHasher, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1876,7 +2002,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Union<'_, T, S> { +impl Clone for Union<'_, T, S, A> { #[inline] fn clone(&self) -> Self { Union { iter: self.iter.clone() } @@ -1884,7 +2010,7 @@ impl Clone for Union<'_, T, S> { } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Union<'_, T, S> +impl FusedIterator for Union<'_, T, S, A> where T: Eq + Hash, S: BuildHasher, @@ -1892,10 +2018,11 @@ where } #[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for Union<'_, T, S> +impl fmt::Debug for Union<'_, T, S, A> where T: fmt::Debug + Eq + Hash, S: BuildHasher, + A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() @@ -1903,10 +2030,11 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, S> Iterator for Union<'a, T, S> +impl<'a, T, S, A> Iterator for Union<'a, T, S, A> where T: Eq + Hash, S: BuildHasher, + A: Allocator, { type Item = &'a T; @@ -1971,7 +2099,12 @@ where /// assert_eq!(vec, ["a", "b", "c", "d", "e"]); /// ``` #[unstable(feature = "hash_set_entry", issue = "60896")] -pub enum Entry<'a, T, S> { +pub enum Entry< + 'a, + T, + S, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { /// An occupied entry. /// /// # Examples @@ -1988,7 +2121,7 @@ pub enum Entry<'a, T, S> { /// Entry::Occupied(_) => { } /// } /// ``` - Occupied(OccupiedEntry<'a, T, S>), + Occupied(OccupiedEntry<'a, T, S, A>), /// A vacant entry. /// @@ -2006,11 +2139,11 @@ pub enum Entry<'a, T, S> { /// Entry::Vacant(_) => { } /// } /// ``` - Vacant(VacantEntry<'a, T, S>), + Vacant(VacantEntry<'a, T, S, A>), } #[unstable(feature = "hash_set_entry", issue = "60896")] -impl fmt::Debug for Entry<'_, T, S> { +impl fmt::Debug for Entry<'_, T, S, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), @@ -2058,12 +2191,17 @@ impl fmt::Debug for Entry<'_, T, S> { /// assert_eq!(set.len(), 2); /// ``` #[unstable(feature = "hash_set_entry", issue = "60896")] -pub struct OccupiedEntry<'a, T, S> { - base: base::OccupiedEntry<'a, T, S>, +pub struct OccupiedEntry< + 'a, + T, + S, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::OccupiedEntry<'a, T, S, A>, } #[unstable(feature = "hash_set_entry", issue = "60896")] -impl fmt::Debug for OccupiedEntry<'_, T, S> { +impl fmt::Debug for OccupiedEntry<'_, T, S, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("OccupiedEntry").field("value", self.get()).finish() } @@ -2098,18 +2236,23 @@ impl fmt::Debug for OccupiedEntry<'_, T, S> { /// assert!(set.contains("b") && set.len() == 2); /// ``` #[unstable(feature = "hash_set_entry", issue = "60896")] -pub struct VacantEntry<'a, T, S> { - base: base::VacantEntry<'a, T, S>, +pub struct VacantEntry< + 'a, + T, + S, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + base: base::VacantEntry<'a, T, S, A>, } #[unstable(feature = "hash_set_entry", issue = "60896")] -impl fmt::Debug for VacantEntry<'_, T, S> { +impl fmt::Debug for VacantEntry<'_, T, S, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("VacantEntry").field(self.get()).finish() } } -impl<'a, T, S> Entry<'a, T, S> { +impl<'a, T, S, A: Allocator> Entry<'a, T, S, A> { /// Sets the value of the entry, and returns an OccupiedEntry. /// /// # Examples @@ -2126,7 +2269,7 @@ impl<'a, T, S> Entry<'a, T, S> { /// ``` #[inline] #[unstable(feature = "hash_set_entry", issue = "60896")] - pub fn insert(self) -> OccupiedEntry<'a, T, S> + pub fn insert(self) -> OccupiedEntry<'a, T, S, A> where T: Hash, S: BuildHasher, @@ -2196,7 +2339,7 @@ impl<'a, T, S> Entry<'a, T, S> { } } -impl OccupiedEntry<'_, T, S> { +impl OccupiedEntry<'_, T, S, A> { /// Gets a reference to the value in the entry. /// /// # Examples @@ -2253,7 +2396,7 @@ impl OccupiedEntry<'_, T, S> { } } -impl<'a, T, S> VacantEntry<'a, T, S> { +impl<'a, T, S, A: Allocator> VacantEntry<'a, T, S, A> { /// Gets a reference to the value that would be used when inserting /// through the `VacantEntry`. /// @@ -2323,7 +2466,7 @@ impl<'a, T, S> VacantEntry<'a, T, S> { } #[inline] - fn insert_entry(self) -> OccupiedEntry<'a, T, S> + fn insert_entry(self) -> OccupiedEntry<'a, T, S, A> where T: Hash, S: BuildHasher,