im_lists/
unrolled.rs

1#[cfg(test)]
2mod proptests;
3
4use smallvec::SmallVec;
5
6use crate::shared::PointerFamily;
7
8use std::cmp::Ordering;
9use std::iter::{FlatMap, FromIterator, Rev};
10use std::marker::PhantomData;
11
12type ConsumingIter<T, P, const N: usize, const G: usize> = FlatMap<
13    NodeIter<T, P, N, G>,
14    // Rev<std::iter::Take<std::vec::IntoIter<T>>>,
15    MaybeCloned<T, P, N, G>,
16    fn(UnrolledList<T, P, N, G>) -> MaybeCloned<T, P, N, G>, // Rev<std::iter::Take<std::vec::IntoIter<T>>>,
17>;
18
19enum MaybeCloned<T: Clone + 'static, P: PointerFamily, const N: usize, const G: usize> {
20    Owned(Rev<std::iter::Take<std::vec::IntoIter<T>>>),
21    Cloned(OwnedNodeIterator<T, P, N, G>),
22}
23
24impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> Iterator
25    for MaybeCloned<T, P, N, G>
26{
27    type Item = T;
28
29    #[inline(always)]
30    fn next(&mut self) -> Option<Self::Item> {
31        match self {
32            MaybeCloned::Owned(o) => o.next(),
33            MaybeCloned::Cloned(r) => r.next(),
34        }
35    }
36
37    #[inline(always)]
38    fn size_hint(&self) -> (usize, Option<usize>) {
39        match self {
40            MaybeCloned::Owned(o) => o.size_hint(),
41            MaybeCloned::Cloned(r) => r.size_hint(),
42        }
43    }
44
45    #[inline(always)]
46    fn fold<B, F>(self, init: B, f: F) -> B
47    where
48        Self: Sized,
49        F: FnMut(B, Self::Item) -> B,
50    {
51        match self {
52            MaybeCloned::Owned(o) => o.fold(init, f),
53            MaybeCloned::Cloned(r) => r.fold(init, f),
54        }
55    }
56
57    #[inline]
58    fn nth(&mut self, n: usize) -> Option<T> {
59        match self {
60            MaybeCloned::Owned(o) => o.nth(n),
61            MaybeCloned::Cloned(r) => r.nth(n),
62        }
63    }
64
65    #[inline]
66    fn find<F>(&mut self, predicate: F) -> Option<Self::Item>
67    where
68        F: FnMut(&Self::Item) -> bool,
69    {
70        match self {
71            MaybeCloned::Owned(o) => o.find(predicate),
72            MaybeCloned::Cloned(r) => r.find(predicate),
73        }
74    }
75}
76
77type RefIter<'a, T, P, const N: usize, const G: usize> = FlatMap<
78    NodeIterRef<'a, T, P, N, G>,
79    Rev<std::slice::Iter<'a, T>>,
80    fn(&'a UnrolledList<T, P, N, G>) -> Rev<std::slice::Iter<'a, T>>,
81>;
82
83type DrainingConsumingIter<T, P, const N: usize, const G: usize> = FlatMap<
84    DrainingNodeIter<T, P, N, G>,
85    Rev<std::iter::Take<std::vec::IntoIter<T>>>,
86    fn(UnrolledList<T, P, N, G>) -> Rev<std::iter::Take<std::vec::IntoIter<T>>>,
87>;
88
89fn empty_list<T: Clone, P: PointerFamily, const N: usize, const G: usize>(
90) -> P::Pointer<UnrolledCell<T, P, N, G>>
91where
92    P::Pointer<UnrolledCell<T, P, N, G>>: 'static,
93{
94    let mut output = None;
95    generic_singleton::get_or_init_thread_local!(
96        || P::new(UnrolledCell::new()),
97        |cell: &P::Pointer<UnrolledCell<T, P, N, G>>| {
98            output = Some(P::clone(cell));
99        }
100    );
101
102    output.unwrap()
103}
104
105#[derive(Eq)]
106pub struct UnrolledList<T: Clone + 'static, P: PointerFamily, const N: usize, const G: usize>(
107    pub(crate) P::Pointer<UnrolledCell<T, P, N, G>>,
108);
109
110impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> Clone
111    for UnrolledList<T, P, N, G>
112{
113    fn clone(&self) -> Self {
114        Self(P::clone(&self.0))
115    }
116}
117
118// Check if these lists are equivalent via the iterator
119impl<T: Clone + PartialEq, P: PointerFamily, const N: usize, const G: usize> PartialEq
120    for UnrolledList<T, P, N, G>
121{
122    fn eq(&self, other: &Self) -> bool {
123        Iterator::eq(self.iter(), other.iter())
124    }
125}
126
127impl<T: Clone + PartialOrd, P: PointerFamily, const N: usize, const G: usize> PartialOrd
128    for UnrolledList<T, P, N, G>
129{
130    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
131        self.iter().partial_cmp(other.iter())
132    }
133}
134
135impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> Default
136    for UnrolledList<T, P, N, G>
137{
138    fn default() -> Self {
139        Self::new()
140    }
141}
142
143impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> UnrolledList<T, P, N, G> {
144    pub fn new() -> Self {
145        // UnrolledList(P::new(UnrolledCell::new()))
146
147        UnrolledList(empty_list::<T, P, N, G>())
148    }
149
150    pub fn as_ptr(&self) -> *const UnrolledCell<T, P, N, G> {
151        P::as_ptr(&self.0)
152    }
153
154    pub fn new_with_capacity() -> Self {
155        UnrolledList(P::new(UnrolledCell::new_with_capacity()))
156    }
157
158    // Get the strong count of the node in question
159    pub fn strong_count(&self) -> usize {
160        P::strong_count(&self.0)
161    }
162
163    // Compare the nodes for pointer equality
164    pub fn ptr_eq(&self, other: &Self) -> bool {
165        P::ptr_eq(&self.0, &other.0)
166    }
167
168    pub fn shared_ptr_eq(&self, other: &Self) -> bool {
169        P::ptr_eq(&self.0.elements, &other.0.elements) && self.0.index == other.0.index
170    }
171
172    pub fn as_ptr_usize(&self) -> usize {
173        P::as_ptr(&self.0) as usize
174    }
175
176    pub fn elements_as_ptr_usize(&self) -> usize {
177        P::as_ptr(&self.0.elements) as usize
178    }
179
180    pub fn next_ptr_as_usize(&self) -> Option<usize> {
181        self.0.next.as_ref().map(|x| x.as_ptr_usize())
182    }
183
184    pub fn current_node_iter(&self) -> impl Iterator<Item = &T> {
185        self.0.elements.iter().take(self.index()).rev()
186    }
187
188    pub fn draining_iterator(self) -> DrainingConsumingWrapper<T, P, N, G> {
189        DrainingConsumingWrapper(self.into_draining_node_iter().flat_map(|x| {
190            let index = x.index();
191
192            P::try_unwrap(x.0)
193                .map(|mut cell| {
194                    P::get_mut(&mut cell.elements)
195                        .map(|vec| std::mem::take(vec).into_iter().take(index).rev())
196                        .unwrap_or_else(|| Vec::new().into_iter().take(0).rev())
197                })
198                .unwrap_or_else(|| Vec::new().into_iter().take(0).rev())
199        }))
200    }
201
202    // #[cfg(test)]
203    pub fn cell_count(&self) -> usize {
204        self.node_iter().count()
205    }
206
207    // This is actually like O(n / 64) which is actually quite nice
208    // Saves us some time
209    pub fn len(&self) -> usize {
210        self.node_iter().map(|node| node.index()).sum()
211    }
212
213    // [0 1 2 3 4 5] -> [6 7 8 9 10]
214    // [5 4 3 2 1] <- [10 9 8 7 6]
215    // This should be O(n / 256)
216    pub fn reverse(self) -> Self {
217        let mut node_iter = self.into_node_iter();
218        let mut left = node_iter.next().expect("This node should always exist");
219        {
220            let inner = P::make_mut(&mut left.0);
221            let elements_mut = P::make_mut(&mut inner.elements);
222
223            if inner.index < elements_mut.len() {
224                elements_mut.truncate(inner.index);
225            }
226
227            elements_mut.reverse();
228            inner.next = None;
229        }
230
231        for mut right in node_iter {
232            let cell = P::make_mut(&mut right.0);
233            let elements_mut = P::make_mut(&mut cell.elements);
234
235            if cell.index < elements_mut.len() {
236                elements_mut.truncate(cell.index);
237            }
238
239            elements_mut.reverse();
240            cell.next = Some(left);
241            left = right;
242        }
243
244        left
245    }
246
247    pub fn last(&self) -> Option<&T> {
248        self.node_iter().last().and_then(|x| x.elements().first())
249    }
250
251    // Should be O(1) always
252    pub fn car(&self) -> Option<T> {
253        self.0.car().cloned()
254    }
255
256    pub fn cons(value: T, other: Self) -> Self {
257        UnrolledCell::cons(value, other)
258    }
259
260    pub fn take(&self, mut count: usize) -> Self {
261        // If the count of the vector
262        if count == 0 {
263            return Self::new();
264        }
265
266        let mut nodes = Vec::new();
267
268        // If we've asked for more elements than this list contains
269        // and there aren't any more to follow, just return this list
270        if count > self.0.index && self.0.next.is_none() {
271            return self.clone();
272        }
273
274        for mut node in self.clone().into_node_iter() {
275            if count < node.0.index {
276                let inner = P::make_mut(&mut node.0);
277                // this is the new tail, point to the end
278                inner.next = None;
279
280                // We want to chop off whatever we need to
281                let elements_mut = P::make_mut(&mut inner.elements);
282
283                // Grab the end of the vector, this will be the new backing
284                let remaining = elements_mut.split_off(inner.index - count);
285                inner.index = count;
286                *elements_mut = remaining;
287                nodes.push(node);
288                break;
289            } else {
290                // Note: We might want to truncate the remaining
291                // elements of the vector.
292                count -= node.0.index;
293                nodes.push(node);
294            }
295        }
296
297        let mut rev_iter = (0..nodes.len()).rev();
298        rev_iter.next();
299
300        for i in rev_iter {
301            let prev = nodes.pop().unwrap();
302
303            if let Some(UnrolledList(cell)) = nodes.get_mut(i) {
304                P::make_mut(cell).next = Some(prev);
305            } else {
306                unreachable!()
307            }
308        }
309
310        nodes.pop().unwrap_or_default()
311    }
312
313    pub fn tail(&self, mut len: usize) -> Option<Self> {
314        // If the count of the vector
315        if len == 0 {
316            return Some(self.clone());
317        }
318
319        for mut node in self.clone().into_node_iter() {
320            if len < node.0.index {
321                let inner = P::make_mut(&mut node.0);
322                // this is the new tail, point to the end
323                // inner.next = None;
324                inner.index -= len;
325                return Some(node);
326            } else {
327                len -= node.0.index;
328            }
329        }
330
331        if len == 0 {
332            return Some(Self::new());
333        }
334
335        None
336    }
337
338    /// Alias for cons_mut
339    pub fn push_front(&mut self, value: T) {
340        self.cons_mut(value)
341    }
342
343    pub fn cons_mut(&mut self, value: T) {
344        let index = self.0.index;
345
346        // This is saying: If we are pointing to a cell where the offset
347        // has been moved to the right but the underlying data has not
348        // yet been truncated, we should attempt to eagerly do so, otherwise
349        // we should fall back to the existing implementation.
350        if self.0.index < self.elements().len() {
351            P::make_mut(&mut P::make_mut(&mut self.0).elements).truncate(index);
352        }
353
354        // TODO cdr here is an issue - only moves the offset, no way to know that its full
355        // Cause its not actually full
356        if self.elements().len() > self.size() - 1 {
357            // Always initialize a vec with half the capacity of the previous one
358            let mut vec = Vec::with_capacity(self.size() / 2);
359            vec.push(value);
360
361            // Make dummy node
362            // return reference to this new node
363            let mut default = UnrolledList(P::new(UnrolledCell {
364                index: 1,
365                elements: P::new(vec),
366                next: Some(self.clone()),
367                size: self.size() * UnrolledCell::<T, P, N, G>::GROWTH_RATE,
368            }));
369
370            std::mem::swap(self, &mut default);
371        } else {
372            match P::get_mut(&mut self.0) {
373                Some(inner) => {
374                    match P::get_mut(&mut inner.elements) {
375                        Some(reference) => {
376                            reference.push(value);
377                            inner.index += 1;
378                        }
379                        // Just check if its bigger than half, point to it.
380                        None => {
381                            self.slow_path_new_node(value);
382                        }
383                    }
384                }
385                None => {
386                    self.slow_path_new_node(value);
387                }
388            }
389        }
390    }
391
392    fn slow_path_new_node(&mut self, value: T) {
393        if self.elements().len() > self.size() / 2 {
394            let mut vec = Vec::with_capacity(N);
395            vec.push(value);
396
397            let mut default = UnrolledList(P::new(UnrolledCell {
398                index: 1,
399                elements: P::new(vec),
400                next: Some(self.clone()),
401                size: N,
402            }));
403
404            std::mem::swap(self, &mut default);
405        } else {
406            let inner = P::make_mut(&mut self.0);
407            inner.cons_mut(value);
408        }
409    }
410
411    // Should be O(1) always
412    // Should also not have to clone
413    pub fn cdr(&self) -> Option<UnrolledList<T, P, N, G>> {
414        self.0.cdr()
415    }
416
417    // Just pop off the internal value and move the index up
418    pub fn pop_front(&mut self) -> Option<T> {
419        let cell = P::make_mut(&mut self.0);
420        let elements = P::make_mut(&mut cell.elements);
421
422        let ret = elements.pop();
423
424        if ret.is_some() {
425            cell.index -= 1;
426        }
427
428        // If after we've popped, its empty, move the pointer to the
429        // next one (if there is one)
430        if cell.index == 0 {
431            if let Some(next) = &mut cell.next {
432                let mut next = std::mem::take(next);
433                std::mem::swap(self, &mut next);
434            }
435        }
436
437        ret
438    }
439
440    pub(crate) fn cdr_exists(&self) -> bool {
441        self.0.index > 1 || self.0.next.is_some()
442    }
443
444    // Returns the cdr of the list
445    // Returns None if the next is empty - otherwise updates self to be the rest
446    pub fn cdr_mut(&mut self) -> Option<&mut Self> {
447        if self.0.index > 1 {
448            // This will allocate a new cell
449            P::make_mut(&mut self.0).index -= 1;
450            Some(self)
451        } else {
452            let inner = P::get_mut(&mut self.0);
453
454            match inner {
455                Some(inner) => {
456                    let output = inner.next.take();
457                    match output {
458                        Some(x) => {
459                            *self = x;
460                            Some(self)
461                        }
462                        None => {
463                            *self = Self::new();
464                            None
465                        }
466                    }
467                }
468                None => match &self.0.next {
469                    Some(x) => {
470                        *self = x.clone();
471                        Some(self)
472                    }
473                    None => {
474                        *self = Self::new();
475                        None
476                    }
477                },
478            }
479        }
480    }
481
482    pub(crate) fn elements(&self) -> &[T] {
483        &self.0.elements
484    }
485
486    fn size(&self) -> usize {
487        self.0.size
488    }
489
490    #[cfg(test)]
491    fn does_node_satisfy_invariant(&self) -> bool {
492        self.elements().len() <= self.size()
493    }
494
495    #[cfg(test)]
496    fn assert_list_invariants(&self) {
497        assert!(self.does_node_satisfy_invariant())
498    }
499
500    pub(crate) fn into_draining_node_iter(self) -> DrainingNodeIter<T, P, N, G> {
501        DrainingNodeIter {
502            cur: Some(self),
503            _inner: PhantomData,
504        }
505    }
506
507    pub(crate) fn into_node_iter(self) -> NodeIter<T, P, N, G> {
508        NodeIter {
509            cur: Some(self),
510            _inner: PhantomData,
511        }
512    }
513
514    pub(crate) fn node_iter(&self) -> NodeIterRef<'_, T, P, N, G> {
515        NodeIterRef {
516            cur: Some(self),
517            _inner: PhantomData,
518        }
519    }
520
521    // TODO investigate using this for the other iterators and see if its faster
522    // Consuming iterators
523    pub fn iter(&self) -> impl Iterator<Item = &'_ T> {
524        self.node_iter()
525            .flat_map(|x| x.elements()[0..x.index()].iter().rev())
526    }
527
528    // Every node must have either CAPACITY elements, or be marked as full
529    // Debateable whether I want them marked as full
530    #[cfg(test)]
531    pub fn assert_invariants(&self) -> bool {
532        self.node_iter().all(Self::does_node_satisfy_invariant)
533    }
534
535    pub fn get(&self, mut index: usize) -> Option<&T> {
536        if index < self.0.index {
537            self.0.elements.get(self.0.index - index - 1)
538        } else {
539            let mut cur = self.0.next.as_ref();
540            index -= self.0.index;
541
542            while let Some(node) = cur {
543                if index < node.0.index {
544                    let node_cap = node.0.index;
545                    return node.0.elements.get(node_cap - index - 1);
546                } else {
547                    cur = node.0.next.as_ref();
548                    index -= node.0.index;
549                }
550            }
551
552            None
553        }
554    }
555
556    // Be able to in place mutate
557    pub fn append_mut(&mut self, other: Self) {
558        if other.elements().is_empty() {
559            return;
560        }
561
562        let mut default = UnrolledList::new();
563        std::mem::swap(self, &mut default);
564
565        default = default.append(other);
566        std::mem::swap(self, &mut default);
567    }
568
569    // Functional append
570    pub fn append(self, other: Self) -> Self {
571        if other.elements().is_empty() {
572            return self;
573        }
574
575        self.into_node_iter()
576            .chain(other.into_node_iter())
577            .collect()
578    }
579
580    // Figure out how in the heck you sort this
581    pub fn sort(&mut self)
582    where
583        T: Ord,
584    {
585        self.sort_by(Ord::cmp)
586    }
587
588    // Figure out how you sort this
589    pub fn sort_by<F>(&mut self, cmp: F)
590    where
591        F: Fn(&T, &T) -> Ordering,
592    {
593        let list = std::mem::take(self);
594        let mut vec = list.into_iter().collect::<Vec<_>>();
595        vec.sort_by(cmp);
596        *self = vec.into();
597    }
598
599    // Append a single value to the end
600    pub fn push_back(&mut self, value: T) {
601        self.extend(std::iter::once(value))
602    }
603
604    pub fn is_empty(&self) -> bool {
605        self.0.elements.is_empty() || self.0.index == 0
606    }
607
608    pub fn index(&self) -> usize {
609        self.0.index
610    }
611}
612
613// Don't blow the stack
614impl<T: Clone + 'static, P: PointerFamily, const N: usize, const G: usize> Drop
615    for UnrolledCell<T, P, N, G>
616{
617    fn drop(&mut self) {
618        let mut cur = self.next.take().map(|x| x.0);
619        loop {
620            match cur {
621                Some(r) => match P::try_unwrap(r) {
622                    Some(UnrolledCell { ref mut next, .. }) => cur = next.take().map(|x| x.0),
623                    _ => return,
624                },
625                _ => return,
626            }
627        }
628    }
629}
630
631pub struct UnrolledCell<T: Clone + 'static, P: PointerFamily, const N: usize, const G: usize> {
632    index: usize,
633    elements: P::Pointer<Vec<T>>,
634    pub(crate) next: Option<UnrolledList<T, P, N, G>>,
635    size: usize,
636}
637
638impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> Clone
639    for UnrolledCell<T, P, N, G>
640{
641    fn clone(&self) -> Self {
642        Self {
643            index: self.index,
644            elements: P::clone(&self.elements),
645            next: self.next.clone(),
646            size: self.size,
647        }
648    }
649}
650
651impl<T: Clone + std::fmt::Debug, P: PointerFamily, const N: usize, const G: usize> std::fmt::Debug
652    for UnrolledList<T, P, N, G>
653{
654    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
655        f.debug_list().entries(self).finish()
656    }
657}
658
659impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> UnrolledCell<T, P, N, G> {
660    const GROWTH_RATE: usize = if G == 0 { 1 } else { G };
661
662    fn new() -> Self {
663        UnrolledCell {
664            index: 0,
665            elements: P::new(Vec::new()),
666            next: None,
667            size: N,
668        }
669    }
670
671    fn new_with_capacity() -> Self {
672        UnrolledCell {
673            index: 0,
674            elements: P::new(Vec::with_capacity(N)),
675            next: None,
676            size: N,
677        }
678    }
679
680    // Speed this up by fixing the indexing
681    fn car(&self) -> Option<&T> {
682        if self.index == 0 {
683            return None;
684        }
685        self.elements.get(self.index - 1)
686    }
687
688    // This _does_ create a boxed representation of the next item. Its possible we don't actually
689    // need to do this, but for now we do
690    fn cdr(&self) -> Option<UnrolledList<T, P, N, G>> {
691        if self.index > 1 {
692            Some(UnrolledList(P::new(self.advance_cursor())))
693        } else {
694            self.next.clone()
695        }
696    }
697
698    fn advance_cursor(&self) -> Self {
699        UnrolledCell {
700            index: self.index - 1,
701            elements: P::clone(&self.elements),
702            next: self.next.clone(),
703            size: self.size,
704        }
705    }
706
707    // TODO make this better
708    fn cons_mut(&mut self, value: T) {
709        let reference = P::make_mut(&mut self.elements);
710        reference.push(value);
711        self.index += 1;
712    }
713
714    // Spill over the values to a new node
715    // otherwise, copy the node and spill over
716    fn cons(value: T, mut cdr: UnrolledList<T, P, N, G>) -> UnrolledList<T, P, N, G> {
717        let size = cdr.size();
718
719        if cdr.elements().len() > size - 1 {
720            UnrolledList(P::new(UnrolledCell {
721                index: 1,
722                elements: P::new(vec![value]),
723                next: Some(cdr),
724                size: size * Self::GROWTH_RATE,
725            }))
726        } else {
727            let inner = P::make_mut(&mut cdr.0);
728            let elements = P::make_mut(&mut inner.elements);
729
730            inner.index += 1;
731            elements.push(value);
732            cdr
733        }
734    }
735}
736
737impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> Extend<T>
738    for UnrolledList<T, P, N, G>
739{
740    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
741        self.append_mut(iter.into_iter().collect())
742    }
743}
744
745pub(crate) struct DrainingNodeIter<
746    T: Clone + 'static,
747    P: PointerFamily,
748    const N: usize,
749    const G: usize,
750> {
751    cur: Option<UnrolledList<T, P, N, G>>,
752    _inner: PhantomData<T>,
753}
754
755impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> Iterator
756    for DrainingNodeIter<T, P, N, G>
757{
758    type Item = UnrolledList<T, P, N, G>;
759    fn next(&mut self) -> Option<Self::Item> {
760        // This is doing allocation. Don't want that.
761
762        if let Some(mut _self) = std::mem::take(&mut self.cur) {
763            if let Some(next) = _self.0.next.as_ref() {
764                // If we can, drop these values!
765                if next.strong_count() == 1 && P::strong_count(&next.0.elements) == 1 {
766                    // self.cur = _self.0.next.clone();
767                    self.cur = P::get_mut(&mut _self.0).and_then(|x| x.next.take());
768                } else {
769                    self.cur = None
770                }
771            } else {
772                self.cur = None
773            }
774
775            Some(_self)
776        } else {
777            None
778        }
779
780        // let mut _self = &mut self.cur;
781        // let mut ret = None;
782
783        // if let Some(next) = _self.as_mut().and_then(|x| x.0.next.as_ref()) {
784        //     // If the next is empty, then we don't want to point to it?
785        //     if next.is_empty() {
786        //         let mut value = None;
787        //         std::mem::swap(&mut self.cur, &mut value);
788        //         return value;
789        //     }
790
791        //     // If we can, drop these values!
792        //     if next.strong_count() == 1 && P::strong_count(&next.0.elements) == 1 {
793        //         // self.cur = _self.0.next.clone();
794        //         // self.cur = P::get_mut(&mut _self.0).and_then(|x| x.next.take());
795        //         // todo!()
796
797        //         let mut value = _self
798        //             .as_mut()
799        //             .and_then(|x| P::get_mut(&mut x.0).and_then(|x| x.next.take()));
800
801        //         std::mem::swap(&mut self.cur, &mut value);
802
803        //         ret = value
804        //     } else {
805        //         self.cur = None
806        //     }
807        // } else {
808        //     self.cur = None
809        // }
810
811        // ret
812    }
813}
814
815pub(crate) struct NodeIter<T: Clone + 'static, P: PointerFamily, const N: usize, const G: usize> {
816    cur: Option<UnrolledList<T, P, N, G>>,
817    _inner: PhantomData<T>,
818}
819
820impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> Iterator for NodeIter<T, P, N, G> {
821    type Item = UnrolledList<T, P, N, G>;
822    fn next(&mut self) -> Option<Self::Item> {
823        if let Some(_self) = std::mem::take(&mut self.cur) {
824            self.cur = _self.0.next.clone();
825            Some(_self)
826        } else {
827            None
828        }
829    }
830}
831
832pub(crate) struct NodeIterRef<
833    'a,
834    T: Clone + 'static,
835    P: PointerFamily,
836    const N: usize,
837    const G: usize,
838> {
839    cur: Option<&'a UnrolledList<T, P, N, G>>,
840    _inner: PhantomData<T>,
841}
842
843impl<'a, T: Clone + 'static, P: PointerFamily, const N: usize, const G: usize> Iterator
844    for NodeIterRef<'a, T, P, N, G>
845{
846    type Item = &'a UnrolledList<T, P, N, G>;
847    fn next(&mut self) -> Option<Self::Item> {
848        if let Some(_self) = &self.cur {
849            let ret_val = self.cur;
850            self.cur = _self.0.next.as_ref();
851            ret_val
852        } else {
853            None
854        }
855    }
856}
857
858pub struct DrainingConsumingWrapper<
859    T: Clone + 'static,
860    P: PointerFamily,
861    const N: usize,
862    const G: usize,
863>(DrainingConsumingIter<T, P, N, G>);
864
865impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> Iterator
866    for DrainingConsumingWrapper<T, P, N, G>
867{
868    type Item = T;
869
870    #[inline(always)]
871    fn next(&mut self) -> Option<Self::Item> {
872        self.0.next()
873    }
874
875    #[inline(always)]
876    fn size_hint(&self) -> (usize, Option<usize>) {
877        self.0.size_hint()
878    }
879
880    #[inline(always)]
881    fn fold<B, F>(self, init: B, f: F) -> B
882    where
883        Self: Sized,
884        F: FnMut(B, Self::Item) -> B,
885    {
886        self.0.fold(init, f)
887    }
888}
889
890pub struct ConsumingWrapper<T: Clone + 'static, P: PointerFamily, const N: usize, const G: usize>(
891    ConsumingIter<T, P, N, G>,
892);
893
894impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> Iterator
895    for ConsumingWrapper<T, P, N, G>
896{
897    type Item = T;
898
899    #[inline(always)]
900    fn next(&mut self) -> Option<Self::Item> {
901        self.0.next()
902    }
903
904    #[inline(always)]
905    fn size_hint(&self) -> (usize, Option<usize>) {
906        self.0.size_hint()
907    }
908
909    #[inline(always)]
910    fn fold<B, F>(self, init: B, f: F) -> B
911    where
912        Self: Sized,
913        F: FnMut(B, Self::Item) -> B,
914    {
915        self.0.fold(init, f)
916    }
917}
918
919struct OwnedNodeIterator<T: Clone + 'static, P: PointerFamily, const N: usize, const G: usize> {
920    list: UnrolledCell<T, P, N, G>,
921}
922
923impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> Iterator
924    for OwnedNodeIterator<T, P, N, G>
925{
926    type Item = T;
927
928    fn next(&mut self) -> Option<Self::Item> {
929        let value = self.list.car().cloned();
930        if self.list.index > 0 {
931            self.list.index -= 1;
932            value
933        } else {
934            None
935        }
936    }
937}
938
939impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> IntoIterator
940    for UnrolledList<T, P, N, G>
941{
942    type Item = T;
943    type IntoIter = ConsumingWrapper<T, P, N, G>;
944
945    fn into_iter(self) -> Self::IntoIter {
946        ConsumingWrapper(self.into_node_iter().flat_map(move |mut x| {
947            // TODO: When doing this, we end up with a really funny
948            // world where we have to _reallocate_ the whole vector. That
949            // is not what we want. What we _actually_ want is to either
950            //
951            // 1. Take the target cell and elements
952            // 2. Or - just clone each underlying element otherwise.
953            //
954            // Otherwise, we end up with a worst of both worlds, since
955            // we need to reallocate the whole vec _just_ to get owned
956            // references.
957            let cell = P::make_mut(&mut x.0);
958
959            match P::get_mut(&mut cell.elements) {
960                Some(vec) => {
961                    let elements = std::mem::take(vec);
962                    MaybeCloned::Owned(elements.into_iter().take(x.index()).rev())
963                }
964                None => MaybeCloned::Cloned(OwnedNodeIterator {
965                    list: cell.to_owned(),
966                }), // None => cell.elements.iter().take(x.index()).rev(),
967            }
968
969            // let vec = P::make_mut(&mut cell.elements);
970
971            // let elements = std::mem::take(vec);
972            // elements.into_iter().take(x.index()).rev()
973        }))
974    }
975}
976
977// TODO have this also expose TryFold
978pub struct IterWrapper<'a, T: Clone + 'static, P: PointerFamily, const N: usize, const G: usize>(
979    RefIter<'a, T, P, N, G>,
980);
981
982impl<'a, T: Clone, P: PointerFamily, const N: usize, const G: usize> Iterator
983    for IterWrapper<'a, T, P, N, G>
984{
985    type Item = &'a T;
986
987    #[inline(always)]
988    fn next(&mut self) -> Option<Self::Item> {
989        self.0.next()
990    }
991
992    #[inline(always)]
993    fn size_hint(&self) -> (usize, Option<usize>) {
994        self.0.size_hint()
995    }
996
997    #[inline(always)]
998    fn fold<B, F>(self, init: B, f: F) -> B
999    where
1000        Self: Sized,
1001        F: FnMut(B, Self::Item) -> B,
1002    {
1003        self.0.fold(init, f)
1004    }
1005}
1006
1007impl<'a, T: Clone, P: PointerFamily, const N: usize, const G: usize> IntoIterator
1008    for &'a UnrolledList<T, P, N, G>
1009{
1010    type Item = &'a T;
1011    type IntoIter = IterWrapper<'a, T, P, N, G>;
1012
1013    #[inline(always)]
1014    fn into_iter(self) -> Self::IntoIter {
1015        IterWrapper(
1016            self.node_iter()
1017                .flat_map(|x| x.elements()[0..x.index()].iter().rev()),
1018        )
1019    }
1020}
1021
1022struct ExponentialChunks<I, const N: usize, const G: usize>
1023where
1024    I: Iterator,
1025{
1026    iter: I,
1027    size: usize,
1028    length: usize,
1029    running_sum: usize,
1030}
1031
1032impl<I, const N: usize, const G: usize> ExponentialChunks<I, N, G>
1033where
1034    I: Iterator,
1035{
1036    fn new(iter: I, length: usize, mut size: usize) -> Self {
1037        let mut running_sum = size;
1038
1039        while running_sum < length {
1040            size *= G;
1041            running_sum += size;
1042        }
1043
1044        Self {
1045            iter,
1046            size,
1047            length,
1048            running_sum: running_sum - size,
1049        }
1050    }
1051}
1052
1053impl<I, const N: usize, const G: usize> Iterator for ExponentialChunks<I, N, G>
1054where
1055    I: Iterator,
1056{
1057    type Item = (usize, Vec<I::Item>);
1058
1059    fn next(&mut self) -> Option<Self::Item> {
1060        let chunk_size = if self.length > self.running_sum {
1061            self.length - self.running_sum
1062        } else {
1063            self.size
1064        };
1065
1066        let iter = self.iter.by_ref().take(chunk_size);
1067
1068        let mut chunk = Vec::with_capacity(iter.size_hint().1.unwrap_or(0));
1069
1070        for item in iter {
1071            chunk.push(item);
1072        }
1073
1074        if chunk.is_empty() {
1075            return None;
1076        }
1077
1078        let result = chunk;
1079        let size = self.size;
1080
1081        self.size /= G;
1082        self.length -= result.len();
1083
1084        Some((size, result))
1085    }
1086}
1087
1088fn from_vec<T: Clone, P: PointerFamily, const N: usize, const G: usize>(
1089    vec: Vec<T>,
1090) -> UnrolledList<T, P, N, G> {
1091    let length = vec.len();
1092
1093    let mut pairs: SmallVec<[UnrolledList<_, _, N, G>; 16]> =
1094        ExponentialChunks::<_, N, G>::new(vec.into_iter(), length, N)
1095            .map(|(size, x)| {
1096                let mut elements = x;
1097                elements.reverse();
1098
1099                UnrolledList(P::new(UnrolledCell {
1100                    index: elements.len(),
1101                    elements: P::new(elements),
1102                    next: None,
1103                    size,
1104                }))
1105            })
1106            .collect();
1107
1108    let mut rev_iter = (0..pairs.len()).rev();
1109    rev_iter.next();
1110
1111    for i in rev_iter {
1112        let prev = pairs.pop().unwrap();
1113
1114        if let Some(UnrolledList(cell)) = pairs.get_mut(i) {
1115            P::get_mut::<UnrolledCell<T, P, N, G>>(cell)
1116                .expect("Only one owner allowed in construction")
1117                .next = Some(prev);
1118        } else {
1119            unreachable!()
1120        }
1121    }
1122
1123    pairs.pop().unwrap_or_else(UnrolledList::new)
1124}
1125
1126// and we'll implement FromIterator
1127// TODO specialize this for the into version?
1128impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> FromIterator<T>
1129    for UnrolledList<T, P, N, G>
1130{
1131    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1132        let reversed: Vec<_> = iter.into_iter().collect();
1133        from_vec(reversed)
1134    }
1135}
1136
1137impl<T: Clone, P: PointerFamily, const N: usize, const G: usize>
1138    FromIterator<UnrolledList<T, P, N, G>> for UnrolledList<T, P, N, G>
1139{
1140    fn from_iter<I: IntoIterator<Item = UnrolledList<T, P, N, G>>>(iter: I) -> Self {
1141        // Links up the nodes
1142        let mut nodes: SmallVec<[_; 16]> = iter.into_iter().collect();
1143
1144        let mut rev_iter = (0..nodes.len()).rev();
1145        rev_iter.next();
1146
1147        for i in rev_iter {
1148            // TODO need to truncate the front of this one
1149            let mut prev = nodes.pop().unwrap();
1150
1151            if let Some(UnrolledList(cell)) = nodes.get_mut(i) {
1152                // Check if this node can fit entirely into the previous one
1153                if cell.elements.len() + prev.0.elements.len() <= prev.0.size {
1154                    let left_inner = P::make_mut(cell);
1155                    let right_inner = P::make_mut(&mut prev.0);
1156
1157                    let left_vector = P::make_mut(&mut left_inner.elements);
1158                    let right_vector = P::make_mut(&mut right_inner.elements);
1159
1160                    // Drop the useless elements
1161                    if left_inner.index < left_vector.len() {
1162                        left_vector.truncate(left_inner.index);
1163                    }
1164
1165                    // TODO
1166                    if right_inner.index < right_vector.len() {
1167                        right_vector.truncate(right_inner.index);
1168                    }
1169
1170                    // Perform the actual move of the values
1171                    right_vector.append(left_vector);
1172
1173                    // Swap the locations now after we've done the update
1174                    std::mem::swap(left_vector, right_vector);
1175                    // Adjust the indices accordingly
1176                    left_inner.index = left_vector.len();
1177                    right_inner.index = 0;
1178
1179                    // Update this node to now point to the right nodes tail
1180                    std::mem::swap(&mut left_inner.next, &mut right_inner.next);
1181                } else {
1182                    P::make_mut(cell).next = Some(prev);
1183                }
1184            } else {
1185                unreachable!()
1186            }
1187        }
1188
1189        nodes.pop().unwrap_or_else(Self::new)
1190    }
1191}
1192
1193impl<'a, T: 'a + Clone, P: 'a + PointerFamily, const N: usize, const G: usize>
1194    FromIterator<&'a UnrolledList<T, P, N, G>> for UnrolledList<T, P, N, G>
1195{
1196    fn from_iter<I: IntoIterator<Item = &'a UnrolledList<T, P, N, G>>>(iter: I) -> Self {
1197        iter.into_iter().cloned().collect()
1198    }
1199}
1200
1201impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> From<Vec<T>>
1202    for UnrolledList<T, P, N, G>
1203{
1204    fn from(vec: Vec<T>) -> Self {
1205        from_vec(vec)
1206    }
1207}
1208
1209impl<T: Clone, P: PointerFamily, const N: usize, const G: usize> From<&[T]>
1210    for UnrolledList<T, P, N, G>
1211{
1212    fn from(vec: &[T]) -> Self {
1213        from_vec(vec.to_vec())
1214    }
1215}
1216
1217#[cfg(test)]
1218mod tests {
1219
1220    use crate::shared::RcPointer;
1221
1222    type RcList<T> = UnrolledList<T, RcPointer, 256, 1>;
1223
1224    use super::*;
1225
1226    #[test]
1227    fn basic_iteration() {
1228        let list: RcList<_> = (0..100usize).into_iter().collect();
1229        let vec: Vec<_> = (0..100usize).into_iter().collect();
1230
1231        Iterator::eq(list.into_iter(), vec.into_iter());
1232    }
1233
1234    #[test]
1235    fn small() {
1236        let list: RcList<_> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9].into_iter().collect();
1237        Iterator::eq(list.into_iter(), (1..=9).into_iter());
1238    }
1239
1240    #[test]
1241    fn append() {
1242        let mut left: RcList<_> = vec![1, 2, 3, 4, 5].into_iter().collect();
1243        let right: RcList<_> = vec![6, 7, 8, 9, 10].into_iter().collect();
1244        left = left.append(right.clone());
1245        left.assert_invariants();
1246        Iterator::eq(left.into_iter(), (1..=10).into_iter());
1247    }
1248
1249    #[test]
1250    fn append_large() {
1251        let mut left: RcList<_> = (0..60).into_iter().collect();
1252        let right: RcList<_> = (60..100).into_iter().collect();
1253
1254        left = left.append(right);
1255
1256        left.assert_invariants();
1257
1258        Iterator::eq(left.into_iter(), (0..100).into_iter());
1259    }
1260}
1261
1262#[cfg(test)]
1263mod iterator_tests {
1264
1265    use super::*;
1266    use crate::shared::RcPointer;
1267
1268    const CAPACITY: usize = 256;
1269
1270    type RcList<T> = UnrolledList<T, RcPointer, 256, 1>;
1271
1272    #[test]
1273    fn check_size() {
1274        println!(
1275            "{}",
1276            std::mem::size_of::<UnrolledCell<usize, RcPointer, 256, 256>>()
1277        );
1278    }
1279
1280    #[test]
1281    fn basic_construction() {
1282        // Assert the left and the right are equivalent after iterating
1283        let list: RcList<_> = (0..1000).into_iter().collect();
1284        let equivalent_vector: Vec<_> = (0..1000).into_iter().collect();
1285
1286        for (left, right) in list.into_iter().zip(equivalent_vector) {
1287            assert_eq!(left, right);
1288        }
1289    }
1290
1291    // Asserts that the iterators are the same
1292    #[test]
1293    fn iterates_all_elements() {
1294        let list: RcList<_> = (0..1000).into_iter().collect();
1295        let equivalent_vector: Vec<_> = (0..1000).into_iter().collect();
1296
1297        assert_eq!(
1298            list.into_iter().count(),
1299            equivalent_vector.into_iter().count()
1300        );
1301    }
1302
1303    // Asserts that the iterator correctly iterates everything
1304    #[test]
1305    fn iterates_correct_amount() {
1306        let count = 1000;
1307        let list: RcList<_> = (0..count).into_iter().collect();
1308
1309        assert_eq!(list.into_iter().count(), count)
1310    }
1311
1312    // TODO verify that this is actually what we want to happen
1313    // In some ways this might not be the performance that we want
1314    // Profile to make sure
1315    #[test]
1316    fn node_appending_coalescing_works() {
1317        // 356
1318        // 256 + 100
1319        let mut left: RcList<_> = (0..CAPACITY + 100).into_iter().collect();
1320
1321        // 400
1322        let right: RcList<_> = (CAPACITY + 100..CAPACITY + 500).into_iter().collect();
1323
1324        left = left.append(right);
1325
1326        for node in left.node_iter() {
1327            println!("{:?}", node.elements().len());
1328        }
1329
1330        // Should have 4 nodes at this point
1331        assert_eq!(left.node_iter().count(), 4);
1332
1333        // 300 should be at 300
1334        assert_eq!(*left.get(300).unwrap(), 300);
1335        left.assert_list_invariants();
1336    }
1337
1338    #[test]
1339    fn length() {
1340        let list: RcList<_> = (0..300).into_iter().collect();
1341        assert_eq!(list.len(), 300);
1342    }
1343
1344    #[test]
1345    fn indexing() {
1346        let list: RcList<_> = (0..300).into_iter().collect();
1347
1348        for i in 0..300 {
1349            assert_eq!(*list.get(i).unwrap(), i);
1350        }
1351    }
1352
1353    #[test]
1354    fn cdr_iterative() {
1355        let mut list: Option<RcList<_>> = Some((0..1000).into_iter().collect());
1356        let mut i = 0;
1357
1358        while let Some(car) = list.as_ref().map(|x| x.car()).flatten() {
1359            assert_eq!(i, car);
1360            list = list.unwrap().cdr();
1361            i += 1;
1362        }
1363    }
1364
1365    #[test]
1366    fn cons_mut_new_node() {
1367        let mut list: RcList<_> = (0..CAPACITY).into_iter().collect();
1368
1369        // Should have 1 node at this point
1370        assert_eq!(list.node_iter().count(), 1);
1371
1372        // Consing should move to a new node
1373        list.cons_mut(1000);
1374
1375        // This should be 2 at this point
1376        assert_eq!(list.node_iter().count(), 2);
1377    }
1378
1379    #[test]
1380    fn cons_mut_list() {
1381        let mut list: RcList<_> = RcList::new();
1382
1383        for i in (0..1000).into_iter().rev() {
1384            list.cons_mut(i);
1385        }
1386
1387        for i in 0..1000 {
1388            assert_eq!(i, *list.get(i).unwrap());
1389        }
1390    }
1391
1392    #[test]
1393    fn empty_list() {
1394        let list: RcList<usize> = <Vec<usize>>::new().into_iter().collect();
1395        assert!(list.is_empty());
1396    }
1397
1398    #[test]
1399    fn cdr_works_successfully() {
1400        let list: RcList<usize> = vec![1, 2, 3, 4, 5].into_iter().collect();
1401
1402        let cdr = list.cdr().unwrap();
1403
1404        let expected_cdr: RcList<usize> = vec![2, 3, 4, 5].into_iter().collect();
1405
1406        assert_eq!(
1407            cdr.into_iter().collect::<Vec<_>>(),
1408            expected_cdr.into_iter().collect::<Vec<_>>()
1409        );
1410    }
1411
1412    #[test]
1413    fn cdr_mut() {
1414        let mut list: RcList<usize> = vec![1, 2, 3usize].into_iter().collect();
1415        assert!(list.cdr_mut().is_some());
1416        assert_eq!(list.len(), 2);
1417        assert!(list.cdr_mut().is_some());
1418        assert_eq!(list.len(), 1);
1419        assert!(list.cdr_mut().is_none());
1420        assert_eq!(list.len(), 0);
1421    }
1422
1423    #[test]
1424    fn reverse() {
1425        let list: RcList<usize> = (0..500).into_iter().collect();
1426        let reversed = list.reverse();
1427
1428        assert!(Iterator::eq(
1429            (0..500).into_iter().rev(),
1430            reversed.into_iter()
1431        ));
1432    }
1433
1434    #[test]
1435    fn last() {
1436        let list: RcList<usize> = RcList::new();
1437        assert!(list.last().is_none());
1438    }
1439
1440    #[test]
1441    fn last_single_node() {
1442        let list: RcList<_> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into();
1443        assert_eq!(list.last().cloned(), Some(10));
1444    }
1445
1446    #[test]
1447    fn last_multiple_nodes() {
1448        let list: RcList<_> = (0..2 * CAPACITY).into_iter().collect();
1449        assert_eq!(list.last().cloned(), Some(CAPACITY * 2 - 1))
1450    }
1451
1452    #[test]
1453    fn take() {
1454        let list: RcList<usize> = (0..2 * CAPACITY).into_iter().collect();
1455        let next = list.take(100);
1456
1457        assert!(Iterator::eq(0..100usize, next.into_iter()))
1458    }
1459
1460    #[test]
1461    fn take_big() {
1462        let list: RcList<usize> = (0..2 * CAPACITY).into_iter().collect();
1463        let next = list.take(CAPACITY + 100);
1464        assert!(Iterator::eq(0..CAPACITY + 100usize, next.into_iter()))
1465    }
1466
1467    #[test]
1468    fn tail() {
1469        let list: RcList<usize> = (0..2 * CAPACITY).into_iter().collect();
1470        let next = list.tail(CAPACITY + 100).unwrap();
1471
1472        assert!(Iterator::eq(
1473            CAPACITY + 100usize..2 * CAPACITY,
1474            next.into_iter()
1475        ))
1476    }
1477
1478    #[test]
1479    fn tail_bigger_than_list() {
1480        let list: RcList<usize> = (0..2 * CAPACITY).into_iter().collect();
1481        let next = list.tail(CAPACITY * 4);
1482
1483        assert!(next.is_none())
1484    }
1485
1486    #[test]
1487    fn pop_front() {
1488        let mut list: RcList<usize> = vec![0, 1, 2, 3].into_iter().collect();
1489        assert_eq!(list.pop_front().unwrap(), 0);
1490        assert_eq!(list.pop_front().unwrap(), 1);
1491        assert_eq!(list.pop_front().unwrap(), 2);
1492        assert_eq!(list.pop_front().unwrap(), 3);
1493        assert!(list.pop_front().is_none())
1494    }
1495
1496    #[test]
1497    fn pop_front_capacity() {
1498        let mut list: RcList<usize> = (0..CAPACITY).into_iter().collect();
1499        list.push_front(100);
1500        assert_eq!(list.cell_count(), 2);
1501        assert_eq!(list.pop_front().unwrap(), 100);
1502        assert_eq!(list.cell_count(), 1);
1503    }
1504
1505    #[test]
1506    fn append_big() {
1507        let mut list: RcList<usize> = (0..3).into_iter().collect();
1508        let big_list: RcList<usize> = (0..CAPACITY - 1).into_iter().collect();
1509
1510        list.append_mut(big_list);
1511    }
1512}
1513
1514#[cfg(test)]
1515mod vlist_iterator_tests {
1516
1517    use super::*;
1518    use crate::shared::RcPointer;
1519
1520    const CAPACITY: usize = 4;
1521
1522    type RcList<T> = UnrolledList<T, RcPointer, 4, 2>;
1523
1524    #[test]
1525    fn basic_construction() {
1526        // Assert the left and the right are equivalent after iterating
1527        let list: RcList<_> = (0..1000).into_iter().collect();
1528        let equivalent_vector: Vec<_> = (0..1000).into_iter().collect();
1529
1530        for (left, right) in list.into_iter().zip(equivalent_vector) {
1531            assert_eq!(left, right);
1532        }
1533    }
1534
1535    // Asserts that the iterators are the same
1536    #[test]
1537    fn iterates_all_elements() {
1538        let list: RcList<_> = (0..1000).into_iter().collect();
1539        let equivalent_vector: Vec<_> = (0..1000).into_iter().collect();
1540
1541        assert_eq!(
1542            list.into_iter().count(),
1543            equivalent_vector.into_iter().count()
1544        );
1545    }
1546
1547    // Asserts that the iterator correctly iterates everything
1548    #[test]
1549    fn iterates_correct_amount() {
1550        let count = 1000;
1551        let list: RcList<_> = (0..count).into_iter().collect();
1552
1553        assert_eq!(list.into_iter().count(), count)
1554    }
1555
1556    #[test]
1557    fn appending_works_as_expected() {
1558        let mut list: RcList<usize> = Vec::<usize>::new().into_iter().collect::<RcList<_>>();
1559
1560        list = list.append(vec![0, 0, 0, 0].into_iter().collect());
1561
1562        assert_eq!(list.cdr().unwrap().len(), 3);
1563    }
1564
1565    #[test]
1566    fn appending_works_as_expected_overflow() {
1567        let mut list: RcList<usize> = Vec::<usize>::new().into_iter().collect::<RcList<_>>();
1568
1569        list = list.append(vec![0, 0, 0, 0, 0].into_iter().collect());
1570
1571        assert_eq!(list.cdr().unwrap().len(), 4);
1572    }
1573
1574    #[test]
1575    fn append_then_pop_front() {
1576        let mut list: UnrolledList<usize, RcPointer, 4, 4> = Vec::<usize>::new()
1577            .into_iter()
1578            .collect::<UnrolledList<_, _, 4, 4>>();
1579
1580        list = list.append(
1581            vec![
1582                1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1583            ]
1584            .into_iter()
1585            .collect(),
1586        );
1587
1588        list.pop_front();
1589
1590        assert_eq!(list.len(), 20);
1591    }
1592
1593    #[test]
1594    fn length() {
1595        let list: RcList<_> = (0..300).into_iter().collect();
1596        assert_eq!(list.len(), 300);
1597    }
1598
1599    #[test]
1600    fn indexing() {
1601        let list: RcList<_> = (0..300).into_iter().collect();
1602
1603        for i in 0..300 {
1604            assert_eq!(*list.get(i).unwrap(), i);
1605        }
1606    }
1607
1608    #[test]
1609    fn cdr_iterative() {
1610        let mut list: Option<RcList<_>> = Some((0..1000).into_iter().collect());
1611        let mut i = 0;
1612
1613        while let Some(car) = list.as_ref().map(|x| x.car()).flatten() {
1614            assert_eq!(i, car);
1615            list = list.unwrap().cdr();
1616            i += 1;
1617        }
1618    }
1619
1620    #[test]
1621    fn cons_mut_new_node() {
1622        let mut list: RcList<_> = (0..4).into_iter().collect();
1623
1624        // Should have 1 node at this point
1625        assert_eq!(list.node_iter().count(), 1);
1626
1627        // Consing should move to a new node
1628        list.cons_mut(1000);
1629
1630        // This should be 2 at this point
1631        assert_eq!(list.node_iter().count(), 2);
1632    }
1633
1634    #[test]
1635    fn cons_mut_list() {
1636        let mut list: RcList<_> = RcList::new();
1637
1638        for i in (0..1000).into_iter().rev() {
1639            list.cons_mut(i);
1640        }
1641
1642        for i in 0..1000 {
1643            assert_eq!(i, *list.get(i).unwrap());
1644        }
1645    }
1646
1647    #[test]
1648    fn empty_list() {
1649        let list: RcList<usize> = <Vec<usize>>::new().into_iter().collect();
1650        assert!(list.is_empty());
1651    }
1652
1653    #[test]
1654    fn cdr_works_successfully() {
1655        let list: RcList<usize> = vec![1, 2, 3, 4, 5].into();
1656
1657        let cdr = list.cdr().unwrap();
1658
1659        let expected_cdr: RcList<usize> = vec![2, 3, 4, 5].into_iter().collect();
1660
1661        assert_eq!(
1662            cdr.into_iter().collect::<Vec<_>>(),
1663            expected_cdr.into_iter().collect::<Vec<_>>()
1664        );
1665    }
1666
1667    #[test]
1668    fn cdr_mut() {
1669        let mut list: RcList<usize> = vec![1, 2, 3usize].into();
1670        assert!(list.cdr_mut().is_some());
1671        assert_eq!(list.len(), 2);
1672        assert!(list.cdr_mut().is_some());
1673        assert_eq!(list.len(), 1);
1674        assert!(list.cdr_mut().is_none());
1675        assert_eq!(list.len(), 0);
1676    }
1677
1678    #[test]
1679    fn reverse() {
1680        let list: RcList<usize> = (0..500).into_iter().collect();
1681        let reversed = list.reverse();
1682
1683        assert!(Iterator::eq(
1684            (0..500).into_iter().rev(),
1685            reversed.into_iter()
1686        ));
1687    }
1688
1689    #[test]
1690    fn last() {
1691        let list: RcList<usize> = RcList::new();
1692        assert!(list.last().is_none());
1693    }
1694
1695    #[test]
1696    fn last_single_node() {
1697        let list: RcList<_> = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into();
1698        assert_eq!(list.last().cloned(), Some(10));
1699    }
1700
1701    #[test]
1702    fn last_multiple_nodes() {
1703        let list: RcList<_> = (0..2 * CAPACITY).into_iter().collect();
1704        assert_eq!(list.last().cloned(), Some(CAPACITY * 2 - 1))
1705    }
1706
1707    #[test]
1708    fn take() {
1709        let list: RcList<usize> = (0..2 * CAPACITY * 32).into_iter().collect();
1710        let next = list.take(100);
1711
1712        assert!(Iterator::eq(0..100usize, next.into_iter()))
1713    }
1714
1715    #[test]
1716    fn take_big() {
1717        let list: RcList<usize> = (0..2 * CAPACITY * 32).into_iter().collect();
1718        let next = list.take(CAPACITY + 100);
1719        assert!(Iterator::eq(0..CAPACITY + 100usize, next.into_iter()))
1720    }
1721
1722    #[test]
1723    fn tail() {
1724        let list: RcList<usize> = (0..2 * CAPACITY * 32).into_iter().collect();
1725        let next = list.tail(CAPACITY + 100).unwrap();
1726
1727        assert!(Iterator::eq(
1728            CAPACITY + 100usize..2 * CAPACITY * 32,
1729            next.into_iter()
1730        ))
1731    }
1732
1733    #[test]
1734    fn tail_bigger_than_list() {
1735        let list: RcList<usize> = (0..2 * CAPACITY).into_iter().collect();
1736        let next = list.tail(CAPACITY * 4);
1737
1738        assert!(next.is_none())
1739    }
1740
1741    #[test]
1742    fn pop_front() {
1743        let mut list: RcList<usize> = vec![0, 1, 2, 3].into_iter().collect();
1744        assert_eq!(list.pop_front().unwrap(), 0);
1745        assert_eq!(list.pop_front().unwrap(), 1);
1746        assert_eq!(list.pop_front().unwrap(), 2);
1747        assert_eq!(list.pop_front().unwrap(), 3);
1748        assert!(list.pop_front().is_none())
1749    }
1750
1751    #[test]
1752    fn pop_front_capacity() {
1753        let mut list: RcList<usize> = (0..CAPACITY).into_iter().collect();
1754        list.push_front(100);
1755        assert_eq!(list.cell_count(), 2);
1756        assert_eq!(list.pop_front().unwrap(), 100);
1757        assert_eq!(list.cell_count(), 1);
1758    }
1759
1760    #[test]
1761    fn append_big() {
1762        let mut list: RcList<usize> = (0..3).into_iter().collect();
1763        let big_list: RcList<usize> = (0..CAPACITY - 1).into_iter().collect();
1764
1765        list.append_mut(big_list);
1766    }
1767}
1768
1769#[cfg(test)]
1770mod reference_counting_correctness {
1771
1772    use super::*;
1773    use crate::shared::RcPointer;
1774    type RcList<T> = UnrolledList<T, RcPointer, 256, 1>;
1775
1776    #[derive(Clone)]
1777    enum Value {
1778        List(RcList<usize>),
1779    }
1780
1781    #[test]
1782    fn test_append() {
1783        fn function_call(args: &mut [Value]) -> Value {
1784            let arg2 = args[1].clone();
1785            let mut arg1 = &mut args[0];
1786
1787            match (&mut arg1, arg2) {
1788                (Value::List(left), Value::List(right)) => {
1789                    assert_eq!(left.strong_count(), 1);
1790                    assert_eq!(right.strong_count(), 2);
1791
1792                    left.append_mut(right);
1793
1794                    assert_eq!(left.strong_count(), 1);
1795                }
1796            }
1797
1798            arg1.clone()
1799        }
1800
1801        let mut args = vec![
1802            Value::List(vec![0, 1, 2, 3, 4, 5].into_iter().collect()),
1803            Value::List(vec![6, 7, 8, 9, 10].into_iter().collect()),
1804        ];
1805
1806        let Value::List(result) = function_call(args.as_mut_slice());
1807
1808        assert_eq!(result.strong_count(), 2);
1809
1810        // Drop everything from the stack
1811        args.clear();
1812        assert_eq!(result.strong_count(), 1);
1813    }
1814}