3 use std
::iter
::FromIterator
;
5 use super::map
::SsoHashMap
;
7 /// Small-storage-optimized implementation of a set.
9 /// Stores elements in a small array up to a certain length
10 /// and switches to `HashSet` when that length is exceeded.
12 // FIXME: Implements subset of HashSet API.
14 // Missing HashSet API:
17 // shrink_to (unstable)
18 // drain_filter (unstable)
20 // get_or_insert/get_or_insert_owned/get_or_insert_with (unstable)
21 // difference/symmetric_difference/intersection/union
22 // is_disjoint/is_subset/is_superset
23 // PartialEq/Eq (requires SsoHashMap implementation)
24 // BitOr/BitAnd/BitXor/Sub
26 pub struct SsoHashSet
<T
> {
27 map
: SsoHashMap
<T
, ()>,
30 /// Adapter function used ot return
31 /// result if SsoHashMap functions into
32 /// result SsoHashSet should return.
34 fn entry_to_key
<K
, V
>((k
, _v
): (K
, V
)) -> K
{
38 impl<T
> SsoHashSet
<T
> {
39 /// Creates an empty `SsoHashSet`.
41 pub fn new() -> Self {
42 Self { map: SsoHashMap::new() }
45 /// Creates an empty `SsoHashSet` with the specified capacity.
47 pub fn with_capacity(cap
: usize) -> Self {
48 Self { map: SsoHashMap::with_capacity(cap) }
51 /// Clears the set, removing all values.
53 pub fn clear(&mut self) {
57 /// Returns the number of elements the set can hold without reallocating.
59 pub fn capacity(&self) -> usize {
63 /// Returns the number of elements in the set.
65 pub fn len(&self) -> usize {
69 /// Returns `true` if the set contains no elements.
71 pub fn is_empty(&self) -> bool
{
75 /// An iterator visiting all elements in arbitrary order.
76 /// The iterator element type is `&'a T`.
78 pub fn iter(&'a
self) -> impl Iterator
<Item
= &'a T
> {
82 /// Clears the set, returning all elements in an iterator.
84 pub fn drain(&mut self) -> impl Iterator
<Item
= T
> + '_
{
85 self.map
.drain().map(entry_to_key
)
89 impl<T
: Eq
+ Hash
> SsoHashSet
<T
> {
90 /// Reserves capacity for at least `additional` more elements to be inserted
91 /// in the `SsoHashSet`. The collection may reserve more space to avoid
92 /// frequent reallocations.
94 pub fn reserve(&mut self, additional
: usize) {
95 self.map
.reserve(additional
)
98 /// Shrinks the capacity of the set as much as possible. It will drop
99 /// down as much as possible while maintaining the internal rules
100 /// and possibly leaving some space in accordance with the resize policy.
102 pub fn shrink_to_fit(&mut self) {
103 self.map
.shrink_to_fit()
106 /// Retains only the elements specified by the predicate.
108 pub fn retain
<F
>(&mut self, mut f
: F
)
110 F
: FnMut(&T
) -> bool
,
112 self.map
.retain(|k
, _v
| f(k
))
115 /// Removes and returns the value in the set, if any, that is equal to the given one.
117 pub fn take(&mut self, value
: &T
) -> Option
<T
> {
118 self.map
.remove_entry(value
).map(entry_to_key
)
121 /// Returns a reference to the value in the set, if any, that is equal to the given value.
123 pub fn get(&self, value
: &T
) -> Option
<&T
> {
124 self.map
.get_key_value(value
).map(entry_to_key
)
127 /// Adds a value to the set.
129 /// If the set did not have this value present, `true` is returned.
131 /// If the set did have this value present, `false` is returned.
133 pub fn insert(&mut self, elem
: T
) -> bool
{
134 self.map
.insert(elem
, ()).is_none()
137 /// Removes a value from the set. Returns whether the value was
138 /// present in the set.
140 pub fn remove(&mut self, value
: &T
) -> bool
{
141 self.map
.remove(value
).is_some()
144 /// Returns `true` if the set contains a value.
146 pub fn contains(&self, value
: &T
) -> bool
{
147 self.map
.contains_key(value
)
151 impl<T
: Eq
+ Hash
> FromIterator
<T
> for SsoHashSet
<T
> {
152 fn from_iter
<I
: IntoIterator
<Item
= T
>>(iter
: I
) -> SsoHashSet
<T
> {
153 let mut set
: SsoHashSet
<T
> = Default
::default();
159 impl<T
> Default
for SsoHashSet
<T
> {
161 fn default() -> Self {
166 impl<T
: Eq
+ Hash
> Extend
<T
> for SsoHashSet
<T
> {
167 fn extend
<I
>(&mut self, iter
: I
)
169 I
: IntoIterator
<Item
= T
>,
171 for val
in iter
.into_iter() {
177 fn extend_one(&mut self, item
: T
) {
182 fn extend_reserve(&mut self, additional
: usize) {
183 self.map
.extend_reserve(additional
)
187 impl<'a
, T
> Extend
<&'a T
> for SsoHashSet
<T
>
189 T
: 'a
+ Eq
+ Hash
+ Copy
,
192 fn extend
<I
: IntoIterator
<Item
= &'a T
>>(&mut self, iter
: I
) {
193 self.extend(iter
.into_iter().cloned());
197 fn extend_one(&mut self, &item
: &'a T
) {
202 fn extend_reserve(&mut self, additional
: usize) {
203 Extend
::<T
>::extend_reserve(self, additional
)
207 impl<T
> IntoIterator
for SsoHashSet
<T
> {
208 type IntoIter
= std
::iter
::Map
<<SsoHashMap
<T
, ()> as IntoIterator
>::IntoIter
, fn((T
, ())) -> T
>;
209 type Item
= <Self::IntoIter
as Iterator
>::Item
;
212 fn into_iter(self) -> Self::IntoIter
{
213 self.map
.into_iter().map(entry_to_key
)
217 impl<'a
, T
> IntoIterator
for &'a SsoHashSet
<T
> {
218 type IntoIter
= std
::iter
::Map
<
219 <&'a SsoHashMap
<T
, ()> as IntoIterator
>::IntoIter
,
220 fn((&'a T
, &'
a ())) -> &'a T
,
222 type Item
= <Self::IntoIter
as Iterator
>::Item
;
225 fn into_iter(self) -> Self::IntoIter
{
226 self.map
.iter().map(entry_to_key
)
230 impl<T
> fmt
::Debug
for SsoHashSet
<T
>
234 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
235 f
.debug_set().entries(self.iter()).finish()