1use std::fmt;
2
3use index_vec::Idx;
4
5use crate::{
6 FromIndexicalIterator, IndexedDomain, IndexedValue, ToIndex, bitset::BitSet,
7 pointer::PointerFamily,
8};
9
10pub struct IndexSet<'a, T: IndexedValue + 'a, S, P: PointerFamily<'a>> {
12 set: S,
13 domain: P::Pointer<IndexedDomain<T>>,
14}
15
16impl<'a, T, S, P> IndexSet<'a, T, S, P>
17where
18 T: IndexedValue + 'a,
19 S: BitSet,
20 P: PointerFamily<'a>,
21{
22 pub fn new(domain: &P::Pointer<IndexedDomain<T>>) -> Self {
24 IndexSet {
25 set: S::empty(domain.len()),
26 domain: domain.clone(),
27 }
28 }
29
30 pub fn indices(&self) -> impl Iterator<Item = T::Index> {
32 self.set.iter().map(T::Index::from_usize)
33 }
34
35 pub fn iter(&self) -> impl Iterator<Item = &T> {
37 self.indices().map(move |idx| self.domain.value(idx))
38 }
39
40 pub fn iter_enumerated(&self) -> impl Iterator<Item = (T::Index, &T)> {
42 self.indices().map(move |idx| (idx, self.domain.value(idx)))
43 }
44
45 pub fn contains<M>(&self, index: impl ToIndex<T, M>) -> bool {
47 let elem = index.to_index(&self.domain);
48 self.set.contains(elem.index())
49 }
50
51 pub fn len(&self) -> usize {
53 self.set.len()
54 }
55
56 pub fn is_empty(&self) -> bool {
58 self.len() == 0
59 }
60
61 pub fn is_superset(&self, other: &IndexSet<'a, T, S, P>) -> bool {
63 self.set.superset(&other.set)
64 }
65
66 pub fn insert<M>(&mut self, elt: impl ToIndex<T, M>) -> bool {
68 let elt = elt.to_index(&self.domain);
69 self.set.insert(elt.index())
70 }
71
72 pub fn remove<M>(&mut self, elt: impl ToIndex<T, M>) -> bool {
74 let elt = elt.to_index(&self.domain);
75 self.set.remove(elt.index())
76 }
77
78 pub fn union(&mut self, other: &IndexSet<'a, T, S, P>) {
80 self.set.union(&other.set);
81 }
82
83 pub fn union_changed(&mut self, other: &IndexSet<'a, T, S, P>) -> bool {
85 self.set.union_changed(&other.set)
86 }
87
88 pub fn subtract(&mut self, other: &IndexSet<'a, T, S, P>) {
90 self.set.subtract(&other.set)
91 }
92
93 pub fn subtract_changed(&mut self, other: &IndexSet<'a, T, S, P>) -> bool {
95 self.set.subtract_changed(&other.set)
96 }
97
98 pub fn intersect(&mut self, other: &IndexSet<'a, T, S, P>) {
100 self.set.intersect(&other.set)
101 }
102
103 pub fn intersect_changed(&mut self, other: &IndexSet<'a, T, S, P>) -> bool {
105 self.set.intersect_changed(&other.set)
106 }
107
108 pub fn insert_all(&mut self) {
110 self.set.insert_all()
111 }
112
113 pub fn clear(&mut self) {
115 self.set.clear();
116 }
117
118 pub fn inner(&self) -> &S {
120 &self.set
121 }
122}
123
124impl<'a, T, S, P> fmt::Debug for IndexSet<'a, T, S, P>
125where
126 T: IndexedValue + fmt::Debug + 'a,
127 S: BitSet,
128 P: PointerFamily<'a>,
129{
130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131 f.debug_set().entries(self.iter()).finish()
132 }
133}
134
135impl<'a, T, S, P> PartialEq for IndexSet<'a, T, S, P>
136where
137 T: IndexedValue + 'a,
138 S: BitSet,
139 P: PointerFamily<'a>,
140{
141 fn eq(&self, other: &Self) -> bool {
142 self.set == other.set
143 }
144}
145
146impl<'a, T, S, P> Eq for IndexSet<'a, T, S, P>
147where
148 T: IndexedValue + 'a,
149 S: BitSet,
150 P: PointerFamily<'a>,
151{
152}
153
154impl<'a, T, S, P> Clone for IndexSet<'a, T, S, P>
155where
156 T: IndexedValue + 'a,
157 S: BitSet,
158 P: PointerFamily<'a>,
159{
160 fn clone(&self) -> Self {
161 IndexSet {
162 set: self.set.clone(),
163 domain: self.domain.clone(),
164 }
165 }
166
167 fn clone_from(&mut self, source: &Self) {
168 self.set.copy_from(&source.set);
169 self.domain = source.domain.clone();
170 }
171}
172
173impl<'a, T, U, S, M, P> FromIndexicalIterator<'a, T, P, M, U> for IndexSet<'a, T, S, P>
174where
175 T: IndexedValue + 'a,
176 S: BitSet,
177 P: PointerFamily<'a>,
178 U: ToIndex<T, M>,
179{
180 fn from_indexical_iter(
181 iter: impl Iterator<Item = U>,
182 domain: &P::Pointer<IndexedDomain<T>>,
183 ) -> Self {
184 let mut set = IndexSet::new(domain);
185 for s in iter {
186 set.insert(s);
187 }
188 set
189 }
190}
191
192#[cfg(test)]
193mod test {
194 use crate::{IndexedDomain, IndexicalIteratorExt, test_utils::TestIndexSet};
195 use std::rc::Rc;
196
197 fn mk(s: &str) -> String {
198 s.to_string()
199 }
200
201 #[test]
202 fn test_indexset() {
203 let d = Rc::new(IndexedDomain::from_iter([mk("a"), mk("b"), mk("c")]));
204 let mut s = TestIndexSet::new(&d);
205 s.insert(mk("a"));
206 let b = d.index(&mk("b"));
207 s.insert(b);
208 assert!(s.contains(mk("a")));
209 assert!(s.contains(mk("b")));
210 assert_eq!(s.len(), 2);
211
212 assert_eq!(
213 [mk("a"), mk("b")]
214 .into_iter()
215 .collect_indexical::<TestIndexSet<_>>(&d),
216 s
217 );
218 assert_eq!(format!("{s:?}"), r#"{"a", "b"}"#)
219 }
220
221 #[cfg(feature = "bitvec")]
222 #[test]
223 fn test_indexset_reffamily() {
224 let d = &IndexedDomain::from_iter([mk("a"), mk("b"), mk("c")]);
225 let mut s = crate::bitset::bitvec::RefIndexSet::new(&d);
226 s.insert(mk("a"));
227 assert!(s.contains(mk("a")));
228
229 let s2 = s.clone();
230 assert!(std::ptr::eq(s.domain, s2.domain));
231 }
232}