1 | //! An immutable set constructed at compile time. |
2 | use core::fmt; |
3 | use core::iter::FusedIterator; |
4 | use core::iter::IntoIterator; |
5 | |
6 | use phf_shared::{PhfBorrow, PhfHash}; |
7 | |
8 | use crate::{map, Map}; |
9 | |
10 | /// An immutable set constructed at compile time. |
11 | /// |
12 | /// ## Note |
13 | /// |
14 | /// The fields of this struct are public so that they may be initialized by the |
15 | /// `phf_set!` macro and code generation. They are subject to change at any |
16 | /// time and should never be accessed directly. |
17 | pub struct Set<T: 'static> { |
18 | #[doc (hidden)] |
19 | pub map: Map<T, ()>, |
20 | } |
21 | |
22 | impl<T> fmt::Debug for Set<T> |
23 | where |
24 | T: fmt::Debug, |
25 | { |
26 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
27 | fmt.debug_set().entries(self).finish() |
28 | } |
29 | } |
30 | |
31 | impl<T> Set<T> { |
32 | /// Returns the number of elements in the `Set`. |
33 | #[inline ] |
34 | pub const fn len(&self) -> usize { |
35 | self.map.len() |
36 | } |
37 | |
38 | /// Returns true if the `Set` contains no elements. |
39 | #[inline ] |
40 | pub const fn is_empty(&self) -> bool { |
41 | self.len() == 0 |
42 | } |
43 | |
44 | /// Returns a reference to the set's internal static instance of the given |
45 | /// key. |
46 | /// |
47 | /// This can be useful for interning schemes. |
48 | pub fn get_key<U: ?Sized>(&self, key: &U) -> Option<&T> |
49 | where |
50 | U: Eq + PhfHash, |
51 | T: PhfBorrow<U>, |
52 | { |
53 | self.map.get_key(key) |
54 | } |
55 | |
56 | /// Returns true if `value` is in the `Set`. |
57 | pub fn contains<U: ?Sized>(&self, value: &U) -> bool |
58 | where |
59 | U: Eq + PhfHash, |
60 | T: PhfBorrow<U>, |
61 | { |
62 | self.map.contains_key(value) |
63 | } |
64 | |
65 | /// Returns an iterator over the values in the set. |
66 | /// |
67 | /// Values are returned in an arbitrary but fixed order. |
68 | pub fn iter(&self) -> Iter<'_, T> { |
69 | Iter { |
70 | iter: self.map.keys(), |
71 | } |
72 | } |
73 | } |
74 | |
75 | impl<T> Set<T> |
76 | where |
77 | T: Eq + PhfHash + PhfBorrow<T>, |
78 | { |
79 | /// Returns true if `other` shares no elements with `self`. |
80 | pub fn is_disjoint(&self, other: &Set<T>) -> bool { |
81 | !self.iter().any(|value: &T| other.contains(value)) |
82 | } |
83 | |
84 | /// Returns true if `other` contains all values in `self`. |
85 | pub fn is_subset(&self, other: &Set<T>) -> bool { |
86 | self.iter().all(|value: &T| other.contains(value)) |
87 | } |
88 | |
89 | /// Returns true if `self` contains all values in `other`. |
90 | pub fn is_superset(&self, other: &Set<T>) -> bool { |
91 | other.is_subset(self) |
92 | } |
93 | } |
94 | |
95 | impl<'a, T> IntoIterator for &'a Set<T> { |
96 | type Item = &'a T; |
97 | type IntoIter = Iter<'a, T>; |
98 | |
99 | fn into_iter(self) -> Iter<'a, T> { |
100 | self.iter() |
101 | } |
102 | } |
103 | |
104 | /// An iterator over the values in a `Set`. |
105 | pub struct Iter<'a, T: 'static> { |
106 | iter: map::Keys<'a, T, ()>, |
107 | } |
108 | |
109 | impl<'a, T> Clone for Iter<'a, T> { |
110 | #[inline ] |
111 | fn clone(&self) -> Self { |
112 | Self { |
113 | iter: self.iter.clone(), |
114 | } |
115 | } |
116 | } |
117 | |
118 | impl<'a, T> fmt::Debug for Iter<'a, T> |
119 | where |
120 | T: fmt::Debug, |
121 | { |
122 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
123 | f.debug_list().entries(self.clone()).finish() |
124 | } |
125 | } |
126 | |
127 | impl<'a, T> Iterator for Iter<'a, T> { |
128 | type Item = &'a T; |
129 | |
130 | fn next(&mut self) -> Option<&'a T> { |
131 | self.iter.next() |
132 | } |
133 | |
134 | fn size_hint(&self) -> (usize, Option<usize>) { |
135 | self.iter.size_hint() |
136 | } |
137 | } |
138 | |
139 | impl<'a, T> DoubleEndedIterator for Iter<'a, T> { |
140 | fn next_back(&mut self) -> Option<&'a T> { |
141 | self.iter.next_back() |
142 | } |
143 | } |
144 | |
145 | impl<'a, T> ExactSizeIterator for Iter<'a, T> {} |
146 | |
147 | impl<'a, T> FusedIterator for Iter<'a, T> {} |
148 | |