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(#[automatically_derived]
impl<T: ::core::clone::Clone> ::core::clone::Clone for ConsNode<T> {
    #[inline]
    fn clone(&self) -> ConsNode<T> {
        ConsNode {
            value: ::core::clone::Clone::clone(&self.value),
            next: ::core::clone::Clone::clone(&self.next),
        }
    }
}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) => f.write_fmt(format_args!("{0:?}", node))write!(f, "{:?}", node),
271            None => f.write_fmt(format_args!("()"))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) => f.write_fmt(format_args!("({0:?}->{1:?})", self.value, node))write!(f, "({:?}->{:?})", self.value, node),
280            None => f.write_fmt(format_args!("({0:?})", self.value))write!(f, "({:?})", self.value),
281        }
282    }
283}