standard_lib/collections/cons/tree/branch.rs
1use std::{fmt::{self, Debug}, mem, ops::Deref, rc::Rc};
2
3use super::{Iter, OwnedIter, RcIter, UniqueIter};
4
5/// A references counted, linked list implemented similar to a cons list. This type is useful as an
6/// list of immutable items with cheap, shallow cloning, that can share nodes with other instances.
7///
8/// When cloned, only the 'head' of the tree is cloned (just an Rc), with all of the elements
9/// included in both list. As a result, the data structure is only mutable from the head, where
10/// elements can be [`push`](Self::push)ed or [`pop`](Self::pop_to_owned)ped. This cheap cloning is
11/// helpful for implementing procedures such that include rollbacks or branching.
12pub struct ConsBranch<T> {
13 pub(crate) inner: Option<Rc<ConsNode<T>>>,
14}
15
16/// Largely intended as an internal type, these nodes are returned by [`ConsTree::into_iter_rc`]
17/// because the interior of the [`Rc`] can't be unwrapped in place.
18///
19/// To help using these nodes, a couple of useful traits have been implemented:
20/// - [`Deref<Target = T> for ConsTreeNode<T>`](Deref) for accessing the contained value.
21/// - [`Into<ConsTree> for Rc<ConsTreeNode<T>>`](Into) for creating a new [`ConsTree`] from an
22/// [`Rc`].
23///
24/// Note that cloning a `ConsTreeNode` directly is _not_ cheap as it is with [`ConsTree`] because
25/// the node contains the value (of type `T`) itself.
26#[derive(Clone)]
27pub struct ConsNode<T> {
28 pub(crate) value: T,
29 pub(crate) next: ConsBranch<T>,
30}
31
32impl<T> ConsBranch<T> {
33 /// Creates a new, empty `ConsTree`.
34 pub const fn new() -> ConsBranch<T> {
35 ConsBranch {
36 inner: None
37 }
38 }
39
40 /// Pushes a new element onto the start of this `ConsTree`, updating this list's head without
41 /// affecting any overlapping lists (shallow clones).
42 pub fn push(&mut self, value: T) {
43 let old = mem::take(&mut self.inner);
44
45 self.inner = Some(Rc::new(ConsNode {
46 value,
47 next: ConsBranch {
48 inner: old
49 },
50 }))
51 }
52
53 /// Returns a reference to the element contained within the head node.
54 pub fn get_head(&self) -> Option<&T> {
55 self.inner.as_deref().map(ConsNode::deref)
56 }
57
58 /// Returns `true` if this `ConsTree` contains no elements.
59 pub const fn is_empty(&self) -> bool {
60 self.inner.is_none()
61 }
62
63 /// Produces a borrowed [`Iterator<Item = &T>`](Iter) over all elements in this list, both
64 /// unique and shared.
65 pub fn iter(&self) -> Iter<'_, T> {
66 Iter {
67 inner: self.inner.as_deref(),
68 }
69 }
70
71 /// Produces an [`Iterator<Item = Rc<ConsTreeNode<T>>>`](RcIter) over all of the underlying
72 /// [`Rc`] instances in this list.
73 ///
74 /// Each referenced element is considered 'shared' for the lifetime of the [`Rc`] produced by
75 /// this iterator. To return a `ConsTree` to being unique, this iterator and all produced
76 /// [`Rc`]s need to be dropped.
77 pub fn into_iter_rc(&self) -> RcIter<T> {
78 RcIter {
79 // We clone here because we are also cloning every step, there is no point taking an
80 // owned self.
81 inner: self.clone(),
82 }
83 }
84
85 /// Returns `true` if this entire list is unique (doesn't share any items with another list).
86 ///
87 /// If this method returns true, [`into_iter_unique`](Self::into_iter_unique) will produce every
88 /// item in the list.
89 pub fn is_unique(&self) -> bool {
90 let mut next = &self.inner;
91 while let Some(node) = next {
92 if !is_unqiue(node) {
93 return false;
94 }
95 next = &node.next.inner;
96 }
97 true
98 }
99
100 /// Returns `true` if the head element of this list is unique.
101 pub fn is_head_unique(&self) -> bool {
102 match &self.inner {
103 Some(node) => is_unqiue(node),
104 None => true,
105 }
106 }
107
108 /// Pops the head element of this list, if it is unique. Otherwise, `self` remains unchanged.
109 pub fn pop_if_unique(&mut self) -> Option<T> {
110 if Rc::get_mut(self.inner.as_mut()?).is_none() {
111 return None;
112 }
113
114 // We've just confirmed that self.inner is Some and that it is unique.
115 let inner = mem::take(&mut self.inner).unwrap();
116 let ConsNode { value, next } = Rc::into_inner(inner).unwrap();
117 self.inner = next.inner;
118
119 Some(value)
120 }
121
122 /// Removes all unique items from this list and returns them as another `ConsTree`.
123 pub fn split_off_unique(&mut self) -> ConsBranch<T> {
124 let mut node = match &mut self.inner {
125 Some(inner) => inner,
126 // The list is empty.
127 None => return ConsBranch::new(),
128 };
129
130 let mut node_mut = match Rc::get_mut(node) {
131 Some(node_mut) => node_mut,
132 // The list contains items, but none are uniquely referenced.
133 None => return ConsBranch::new(),
134 };
135
136 loop {
137 // We need to borrow the next node once once as a reference and then conditionally, as a
138 // mutable reference.
139 if let Some(true) = node_mut.next.inner.as_ref().map(is_unqiue) {
140 // We know that node_mut.next.inner is Some, but we couldn't borrow it as a
141 // mutable reference until we knew it was unique.
142 node = node_mut.next.inner.as_mut().unwrap();
143 } else {
144 // node_mut.next.inner is either None or a non unique node. For both cases, we take
145 // it as the shared head of the tree and replace it with a None.
146 let shared_head = mem::take(&mut node_mut.next.inner);
147 // We then replace the inner value with it, leaving self as entirely shared and
148 // returning the head of the unique portion.
149 return ConsBranch {
150 inner: mem::replace(&mut self.inner, shared_head),
151 };
152 }
153
154 // We've already checked that the node is unqiue, and diverged otherwise.
155 // Rc is !Sync, so we don't have to worry about TOCTOU.
156 node_mut = Rc::get_mut(node).unwrap();
157 }
158 }
159
160 /// Produces an [`Iterator<Item = T>`](UniqueIter) over the elements in this list, producing
161 /// owned values until a shared element is found.
162 ///
163 /// This iterator does no cloning and produces owned items by completely ignoring any elements
164 /// that are shared by other lists.
165 ///
166 /// If called on every clone of a single initial `ConsTree`, every element of the tree will be
167 /// returned by an iterator only once.
168 pub const fn into_iter_unique(self) -> UniqueIter<T> {
169 UniqueIter {
170 inner: self,
171 }
172 }
173}
174
175impl<T: Clone> ConsBranch<T> {
176 /// Pops the head element from this list, cloning if it is shared by another `ConsTree`.
177 /// Regardless of if a clone is required, the head of this list will be updated.
178 pub fn pop_to_owned(&mut self) -> Option<T> {
179 let inner = mem::take(&mut self.inner);
180
181 match inner {
182 Some(node) => {
183 let ConsNode { value, next } = Rc::unwrap_or_clone(node);
184 self.inner = next.inner;
185 Some(value)
186 },
187 None => {
188 self.inner = inner;
189 None
190 },
191 }
192 }
193
194 /// Produces an [`Iterator<Item = T>`](OwnedIter) over all elements in this list, returning
195 /// owned items by cloning any shared elements.
196 pub const fn into_iter_owned(self) -> OwnedIter<T> {
197 OwnedIter {
198 inner: self,
199 }
200 }
201
202 /// Produces a deep clone of this `ConsTree`. The result has a clone of every element in this
203 /// list, without sharing any. The result is unique.
204 pub fn deep_clone(&self) -> ConsBranch<T> {
205 let refs: Vec<_> = self.iter().collect();
206
207 refs.into_iter()
208 .rev()
209 .cloned()
210 .collect()
211 }
212}
213
214impl<T> Clone for ConsBranch<T> {
215 /// Creates a cheap (shallow) clone of this `ConsTree`, with all the same underlying elements.
216 /// After cloning, all elements of the list are considered 'shared' between the original list and
217 /// the clone.
218 fn clone(&self) -> Self {
219 Self {
220 inner: self.inner.clone()
221 }
222 }
223}
224
225fn is_unqiue<T>(value: &Rc<T>) -> bool {
226 Rc::strong_count(value) == 1
227}
228
229impl<T> Default for ConsBranch<T> {
230 fn default() -> Self {
231 Self::new()
232 }
233}
234
235impl<T> FromIterator<T> for ConsBranch<T> {
236 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
237 let mut res = ConsBranch::new();
238 for item in iter {
239 res.push(item);
240 }
241 res
242 }
243}
244
245impl<T> From<Rc<ConsNode<T>>> for ConsBranch<T> {
246 fn from(value: Rc<ConsNode<T>>) -> Self {
247 ConsBranch {
248 inner: Some(value),
249 }
250 }
251}
252
253impl<T> Deref for ConsNode<T> {
254 type Target = T;
255
256 fn deref(&self) -> &Self::Target {
257 &self.value
258 }
259}
260
261impl<T> AsRef<T> for ConsNode<T> {
262 fn as_ref(&self) -> &T {
263 self.deref()
264 }
265}
266
267impl<T: Debug> Debug for ConsBranch<T> {
268 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
269 match &self.inner {
270 Some(node) => write!(f, "{:?}", node),
271 None => write!(f, "()"),
272 }
273 }
274}
275
276impl<T: Debug> Debug for ConsNode<T> {
277 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
278 match &self.next.inner {
279 Some(node) => write!(f, "({:?}->{:?})", self.value, node),
280 None => write!(f, "({:?})", self.value),
281 }
282 }
283}