Skip to main content

disjoint_collections/
vec.rs

1use std::cell::Cell;
2
3/// Disjoint array based on [`Vec`].
4#[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}