disjoint_collections/
vec.rs1use std::cell::Cell;
2
3#[derive(Debug, Clone)]
5pub struct DisjointVec<T>(Vec<Item<T>>);
6
7impl<T> Default for DisjointVec<T> {
8 fn default() -> Self {
9 Self::new()
10 }
11}
12
13impl<T> DisjointVec<T> {
14 pub fn new() -> Self {
15 Self(Vec::new())
16 }
17
18 pub fn with_capacity(capacity: usize) -> Self {
19 Self(Vec::with_capacity(capacity))
20 }
21
22 pub fn len(&self) -> usize {
23 self.0.len()
24 }
25
26 pub fn is_empty(&self) -> bool {
27 self.0.is_empty()
28 }
29
30 pub fn push(&mut self, value: T) -> usize {
31 let i = self.len();
32 self.0.push(Item::Class(value));
33 i
34 }
35
36 pub fn class_of(&self, i: usize) -> Option<usize> {
37 Some(match self.0.get(i)? {
38 Item::Class(_) => i,
39 Item::Indirection(j) => {
40 let k = self.class_of(j.get())?;
41 j.set(k);
42 k
43 }
44 })
45 }
46
47 pub fn get_with_class(&self, i: usize) -> Option<(usize, &T)> {
48 Some(match self.0.get(i)? {
49 Item::Class(t) => (i, t),
50 Item::Indirection(j) => {
51 let (k, t) = self.get_with_class(j.get())?;
52 j.set(k);
53 (k, t)
54 }
55 })
56 }
57
58 pub fn get(&self, i: usize) -> Option<&T> {
59 self.get_with_class(i).map(|(_, v)| v)
60 }
61
62 pub fn get_mut_with_class(&mut self, mut i: usize) -> Option<(usize, &mut T)> {
63 loop {
64 match self.0.get(i)? {
65 Item::Class(_) => {
66 break Some((i, self.0.get_mut(i).unwrap().as_value_mut().unwrap()))
67 }
68 Item::Indirection(j) => i = j.get(),
69 }
70 }
71 }
72
73 pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
74 self.get_mut_with_class(i).map(|(_, v)| v)
75 }
76
77 pub fn replace(&mut self, i: usize, value: T) -> Result<T, T> {
78 match self.get_mut(i) {
79 Some(current_value) => Ok(std::mem::replace(current_value, value)),
80 None => Err(value),
81 }
82 }
83
84 pub fn merge(&mut self, a: usize, b: usize, f: impl FnOnce(T, T) -> T) -> Option<usize> {
85 if let Some(mut ac) = self.class_of(a) {
86 if let Some(mut bc) = self.class_of(b) {
87 if ac == bc {
88 return Some(ac);
89 } else {
90 let av = std::mem::replace(&mut self.0[ac], Item::Indirection(Cell::new(0)))
91 .into_value()
92 .unwrap();
93 let bv = std::mem::replace(&mut self.0[bc], Item::Indirection(Cell::new(0)))
94 .into_value()
95 .unwrap();
96 let value = f(av, bv);
97
98 if bc < ac {
99 std::mem::swap(&mut ac, &mut bc);
100 }
101
102 self.0[ac] = Item::Class(value);
103 self.0[bc] = Item::Indirection(Cell::new(ac));
104 return Some(ac);
105 }
106 }
107 }
108
109 None
110 }
111
112 pub fn try_merge<E>(
113 &mut self,
114 a: usize,
115 b: usize,
116 f: impl FnOnce(T, T) -> Result<T, E>,
117 ) -> Result<Option<usize>, E> {
118 if let Some(mut ac) = self.class_of(a) {
119 if let Some(mut bc) = self.class_of(b) {
120 if ac == bc {
121 return Ok(Some(ac));
122 } else {
123 let av = std::mem::replace(&mut self.0[ac], Item::Indirection(Cell::new(0)))
124 .into_value()
125 .unwrap();
126 let bv = std::mem::replace(&mut self.0[bc], Item::Indirection(Cell::new(0)))
127 .into_value()
128 .unwrap();
129 match f(av, bv) {
130 Ok(value) => {
131 if bc < ac {
132 std::mem::swap(&mut ac, &mut bc);
133 }
134
135 self.0[ac] = Item::Class(value);
136 self.0[bc] = Item::Indirection(Cell::new(ac));
137 return Ok(Some(ac));
138 }
139 Err(e) => {
140 self.0.clear();
141 return Err(e);
142 }
143 }
144 }
145 }
146 }
147
148 Ok(None)
149 }
150
151 pub fn try_merge_or_restore<E>(
152 &mut self,
153 a: usize,
154 b: usize,
155 f: impl FnOnce(T, T) -> Result<T, (E, T, T)>,
156 ) -> Result<Option<usize>, E> {
157 if let Some(mut ac) = self.class_of(a) {
158 if let Some(mut bc) = self.class_of(b) {
159 if ac == bc {
160 return Ok(Some(ac));
161 } else {
162 let av = std::mem::replace(&mut self.0[ac], Item::Indirection(Cell::new(0)))
163 .into_value()
164 .unwrap();
165 let bv = std::mem::replace(&mut self.0[bc], Item::Indirection(Cell::new(0)))
166 .into_value()
167 .unwrap();
168 match f(av, bv) {
169 Ok(value) => {
170 if bc < ac {
171 std::mem::swap(&mut ac, &mut bc);
172 }
173
174 self.0[ac] = Item::Class(value);
175 self.0[bc] = Item::Indirection(Cell::new(ac));
176 return Ok(Some(ac));
177 }
178 Err((e, av, bv)) => {
179 self.0[ac] = Item::Class(av);
180 self.0[bc] = Item::Class(bv);
181 return Err(e);
182 }
183 }
184 }
185 }
186 }
187
188 Ok(None)
189 }
190
191 pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> DisjointVec<U> {
192 DisjointVec(self.0.into_iter().map(|item| item.map(&mut f)).collect())
193 }
194
195 pub fn classes(&self) -> Classes<'_, T> {
196 Classes(self.0.iter().enumerate())
197 }
198
199 pub fn into_classes(self) -> IntoClasses<T> {
200 IntoClasses(self.0.into_iter().enumerate())
201 }
202}
203
204impl<T> Extend<T> for DisjointVec<T> {
205 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
206 self.0.extend(iter.into_iter().map(Item::Class));
207 }
208}
209
210impl<T> FromIterator<T> for DisjointVec<T> {
211 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
212 let mut result = Self::default();
213 result.extend(iter);
214 result
215 }
216}
217
218#[derive(Debug, Clone)]
219enum Item<T> {
220 Class(T),
221 Indirection(Cell<usize>),
222}
223
224impl<T> Item<T> {
225 fn into_value(self) -> Option<T> {
226 match self {
227 Self::Class(t) => Some(t),
228 Self::Indirection(_) => None,
229 }
230 }
231
232 fn as_value_mut(&mut self) -> Option<&mut T> {
233 match self {
234 Self::Class(t) => Some(t),
235 Self::Indirection(_) => None,
236 }
237 }
238
239 pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Item<U> {
240 match self {
241 Self::Class(t) => Item::Class(f(t)),
242 Self::Indirection(c) => Item::Indirection(c),
243 }
244 }
245}
246
247pub struct Classes<'a, T>(std::iter::Enumerate<std::slice::Iter<'a, Item<T>>>);
248
249impl<'a, T> Iterator for Classes<'a, T> {
250 type Item = (usize, &'a T);
251
252 fn next(&mut self) -> Option<Self::Item> {
253 for (i, item) in &mut self.0 {
254 if let Item::Class(t) = item {
255 return Some((i, t));
256 }
257 }
258
259 None
260 }
261}
262
263pub struct IntoClasses<T>(std::iter::Enumerate<std::vec::IntoIter<Item<T>>>);
264
265impl<T> Iterator for IntoClasses<T> {
266 type Item = (usize, T);
267
268 fn next(&mut self) -> Option<Self::Item> {
269 for (i, item) in &mut self.0 {
270 if let Item::Class(t) = item {
271 return Some((i, t));
272 }
273 }
274
275 None
276 }
277}