1use std::{fmt::{self, Debug}, mem, ops::Deref, rc::Rc};
23use super::{Iter, OwnedIter, RcIter, UniqueIter};
45/// 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.
12#[derive(#[automatically_derived]
impl<T: ::core::cmp::PartialEq> ::core::cmp::PartialEq for ConsBranch<T> {
#[inline]
fn eq(&self, other: &ConsBranch<T>) -> bool { self.inner == other.inner }
}PartialEq, #[automatically_derived]
impl<T: ::core::cmp::Eq> ::core::cmp::Eq for ConsBranch<T> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Option<Rc<ConsNode<T>>>>;
}
}Eq, #[automatically_derived]
impl<T: ::core::hash::Hash> ::core::hash::Hash for ConsBranch<T> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.inner, state)
}
}Hash)]
13pub struct ConsBranch<T> {
14pub(crate) inner: Option<Rc<ConsNode<T>>>,
15}
1617/// Largely intended as an internal type, these nodes are returned by [`ConsBranch::into_iter_rc`]
18/// because the interior of the [`Rc`] can't be unwrapped in place.
19///
20/// To help using these nodes, a couple of useful traits have been implemented:
21/// - [`Deref<Target = T> for ConsNode<T>`](Deref) for accessing the contained value.
22/// - [`Into<ConsBranch> for Rc<ConsNode<T>>`](Into) for creating a new [`ConsBranch`] from an
23/// [`Rc`].
24///
25/// Note that cloning a `ConsNode` directly is _not_ cheap as it is with [`ConsBranch`] because
26/// the node contains the value (of type `T`) itself.
27#[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, #[automatically_derived]
impl<T: ::core::cmp::PartialEq> ::core::cmp::PartialEq for ConsNode<T> {
#[inline]
fn eq(&self, other: &ConsNode<T>) -> bool {
self.value == other.value && self.next == other.next
}
}PartialEq, #[automatically_derived]
impl<T: ::core::cmp::Eq> ::core::cmp::Eq for ConsNode<T> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<T>;
let _: ::core::cmp::AssertParamIsEq<ConsBranch<T>>;
}
}Eq, #[automatically_derived]
impl<T: ::core::hash::Hash> ::core::hash::Hash for ConsNode<T> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.value, state);
::core::hash::Hash::hash(&self.next, state)
}
}Hash)]
28pub struct ConsNode<T> {
29pub(crate) value: T,
30pub(crate) next: ConsBranch<T>,
31}
3233impl<T> ConsBranch<T> {
34/// Creates a new, empty `ConsBranch`.
35pub const fn new() -> ConsBranch<T> {
36 ConsBranch {
37 inner: None
38}
39 }
4041/// Pushes a new element onto the start of this `ConsBranch`, updating this list's head without
42 /// affecting any overlapping lists (shallow clones).
43pub fn push(&mut self, value: T) {
44let old = mem::take(&mut self.inner);
4546self.inner = Some(Rc::new(ConsNode {
47 value,
48 next: ConsBranch {
49 inner: old
50 },
51 }))
52 }
5354/// Returns a reference to the element contained within the head node.
55pub fn get_head(&self) -> Option<&T> {
56self.inner.as_deref().map(ConsNode::deref)
57 }
5859/// Returns `true` if this `ConsBranch` contains no elements.
60pub const fn is_empty(&self) -> bool {
61self.inner.is_none()
62 }
6364/// Produces a borrowed [`Iterator<Item = &T>`](Iter) over all elements in this list, both
65 /// unique and shared.
66pub fn iter(&self) -> Iter<'_, T> {
67 Iter {
68 inner: self.inner.as_deref(),
69 }
70 }
7172/// Produces an [`Iterator<Item = Rc<ConsNode<T>>>`](RcIter) over all of the underlying [`Rc`]
73 /// instances in this list.
74 ///
75 /// Each referenced element is considered 'shared' for the lifetime of the [`Rc`] produced by
76 /// this iterator. To return a `ConsBranch` to being unique, this iterator and all produced
77 /// [`Rc`]s need to be dropped.
78pub fn into_iter_rc(&self) -> RcIter<T> {
79 RcIter {
80// We clone here because we are also cloning every step, there is no point taking an
81 // owned self.
82inner: self.clone(),
83 }
84 }
8586/// Returns `true` if this entire list is unique (doesn't share any items with another list).
87 ///
88 /// If this method returns true, [`into_iter_unique`](Self::into_iter_unique) will produce every
89 /// item in the list.
90pub fn is_unique(&self) -> bool {
91let mut next = &self.inner;
92while let Some(node) = next {
93if !is_unqiue(node) {
94return false;
95 }
96 next = &node.next.inner;
97 }
98true
99}
100101/// Returns `true` if the head element of this list is unique.
102pub fn is_head_unique(&self) -> bool {
103match &self.inner {
104Some(node) => is_unqiue(node),
105None => true,
106 }
107 }
108109/// Pops the head element of this list, if it is unique. Otherwise, `self` remains unchanged.
110pub fn pop_if_unique(&mut self) -> Option<T> {
111if Rc::get_mut(self.inner.as_mut()?).is_none() {
112return None;
113 }
114115// We've just confirmed that self.inner is Some and that it is unique.
116let inner = mem::take(&mut self.inner).unwrap();
117let ConsNode { value, next } = Rc::into_inner(inner).unwrap();
118self.inner = next.inner;
119120Some(value)
121 }
122123/// Removes all unique items from this list and returns them as another `ConsBranch`.
124pub fn split_off_unique(&mut self) -> ConsBranch<T> {
125let mut node = match &mut self.inner {
126Some(inner) => inner,
127// The list is empty.
128None => return ConsBranch::new(),
129 };
130131let mut node_mut = match Rc::get_mut(node) {
132Some(node_mut) => node_mut,
133// The list contains items, but none are uniquely referenced.
134None => return ConsBranch::new(),
135 };
136137loop {
138// We need to borrow the next node once once as a reference and then conditionally, as a
139 // mutable reference.
140if let Some(true) = node_mut.next.inner.as_ref().map(is_unqiue) {
141// We know that node_mut.next.inner is Some, but we couldn't borrow it as a
142 // mutable reference until we knew it was unique.
143node = node_mut.next.inner.as_mut().unwrap();
144 } else {
145// node_mut.next.inner is either None or a non unique node. For both cases, we take
146 // it as the shared head of the tree and replace it with a None.
147let shared_head = mem::take(&mut node_mut.next.inner);
148// We then replace the inner value with it, leaving self as entirely shared and
149 // returning the head of the unique portion.
150return ConsBranch {
151 inner: mem::replace(&mut self.inner, shared_head),
152 };
153 }
154155// We've already checked that the node is unqiue, and diverged otherwise.
156 // Rc is !Sync, so we don't have to worry about TOCTOU.
157node_mut = Rc::get_mut(node).unwrap();
158 }
159 }
160161/// Produces an [`Iterator<Item = T>`](UniqueIter) over the elements in this list, producing
162 /// owned values until a shared element is found.
163 ///
164 /// This iterator does no cloning and produces owned items by completely ignoring any elements
165 /// that are shared by other lists.
166 ///
167 /// If called on every clone of a single initial `ConsBranch`, every element of the tree will be
168 /// returned by an iterator only once.
169pub const fn into_iter_unique(self) -> UniqueIter<T> {
170 UniqueIter {
171 inner: self,
172 }
173 }
174}
175176impl<T: Clone> ConsBranch<T> {
177/// Pops the head element from this list, cloning if it is shared by another `ConsBranch`.
178 /// Regardless of if a clone is required, the head of this list will be updated.
179pub fn pop_to_owned(&mut self) -> Option<T> {
180let inner = mem::take(&mut self.inner);
181182match inner {
183Some(node) => {
184let ConsNode { value, next } = Rc::unwrap_or_clone(node);
185self.inner = next.inner;
186Some(value)
187 },
188None => {
189self.inner = inner;
190None
191},
192 }
193 }
194195/// Produces an [`Iterator<Item = T>`](OwnedIter) over all elements in this list, returning
196 /// owned items by cloning any shared elements.
197pub const fn into_iter_owned(self) -> OwnedIter<T> {
198 OwnedIter {
199 inner: self,
200 }
201 }
202203/// Produces a deep clone of this `ConsBranch`. The result has a clone of every element in this
204 /// list, without sharing any. The result is unique.
205pub fn deep_clone(&self) -> ConsBranch<T> {
206let refs: Vec<_> = self.iter().collect();
207208 refs.into_iter()
209 .rev()
210 .cloned()
211 .collect()
212 }
213}
214215impl<T> Clone for ConsBranch<T> {
216/// Creates a cheap (shallow) clone of this `ConsBranch`, with all the same underlying elements.
217 /// After cloning, all elements of the list are considered 'shared' between the original list
218 /// and the clone.
219fn clone(&self) -> Self {
220Self {
221 inner: self.inner.clone()
222 }
223 }
224}
225226fn is_unqiue<T>(value: &Rc<T>) -> bool {
227 Rc::strong_count(value) == 1
228}
229230impl<T> Default for ConsBranch<T> {
231fn default() -> Self {
232Self::new()
233 }
234}
235236impl<T> FromIterator<T> for ConsBranch<T> {
237fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
238let mut res = ConsBranch::new();
239for item in iter {
240 res.push(item);
241 }
242 res
243 }
244}
245246impl<T> From<Rc<ConsNode<T>>> for ConsBranch<T> {
247fn from(value: Rc<ConsNode<T>>) -> Self {
248 ConsBranch {
249 inner: Some(value),
250 }
251 }
252}
253254impl<T> Deref for ConsNode<T> {
255type Target = T;
256257fn deref(&self) -> &Self::Target {
258&self.value
259 }
260}
261262impl<T> AsRef<T> for ConsNode<T> {
263fn as_ref(&self) -> &T {
264self.deref()
265 }
266}
267268impl<T: Debug> Debug for ConsBranch<T> {
269fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
270match &self.inner {
271Some(node) => f.write_fmt(format_args!("{0:?}", node))write!(f, "{:?}", node),
272None => f.write_fmt(format_args!("()"))write!(f, "()"),
273 }
274 }
275}
276277impl<T: Debug> Debug for ConsNode<T> {
278fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279match &self.next.inner {
280Some(node) => f.write_fmt(format_args!("({0:?}->{1:?})", self.value, node))write!(f, "({:?}->{:?})", self.value, node),
281None => f.write_fmt(format_args!("({0:?})", self.value))write!(f, "({:?})", self.value),
282 }
283 }
284}