orx_split_vec/growth/recursive/
append.rs

1use crate::{IntoFragments, Recursive, SplitVec};
2
3impl<T> SplitVec<T, Recursive> {
4    /// Consumes and appends `other` vector into this vector in constant time without memory copies.
5    ///
6    /// # Example
7    ///
8    /// ```rust
9    /// use orx_split_vec::*;
10    ///
11    /// let mut recursive = SplitVec::with_recursive_growth();
12    ///
13    /// recursive.push('a');
14    /// assert_eq!(recursive, &['a']);
15    ///
16    /// recursive.append(vec!['b', 'c']);
17    /// assert_eq!(recursive, &['a', 'b', 'c']);
18    ///
19    /// recursive.append(vec![vec!['d'], vec!['e', 'f']]);
20    /// assert_eq!(recursive, &['a', 'b', 'c', 'd', 'e', 'f']);
21    ///
22    /// let other_split_vec: SplitVec<_> = vec!['g', 'h'].into();
23    /// recursive.append(other_split_vec);
24    /// assert_eq!(recursive, &['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']);
25    /// ```
26    pub fn append<I: IntoFragments<T>>(&mut self, other: I) {
27        let fragments = other.into_fragments();
28        for fragment in fragments {
29            self.len += fragment.len();
30            self.fragments.push(fragment);
31        }
32        // TODO: does this break internal structure of the vec; be careful on its impact on linked-list
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use orx_pinned_vec::PinnedVec;
40
41    #[test]
42    fn append_full_fragment_when_empty() {
43        let mut vec = SplitVec::with_recursive_growth();
44        assert_eq!(vec.capacity(), 4);
45
46        vec.append(alloc::vec![0, 1, 2]);
47        assert_eq!(vec.fragments().len(), 2);
48        assert_eq!(vec.capacity(), 4 + 3);
49
50        vec.push(3);
51        assert_eq!(vec.fragments().len(), 3);
52        assert_eq!(vec.capacity(), 4 + 3 + 6);
53
54        assert_eq!(vec, &[0, 1, 2, 3]);
55    }
56
57    #[test]
58    fn append_half_fragment_when_empty() {
59        let mut vec = SplitVec::with_recursive_growth();
60        assert_eq!(vec.capacity(), 4);
61
62        let mut append = alloc::vec::Vec::with_capacity(4);
63        append.extend_from_slice(&[0, 1, 2]);
64        vec.append(append);
65        assert_eq!(vec.fragments().len(), 2);
66        assert_eq!(vec.capacity(), 4 + 4);
67
68        vec.push(3);
69        assert_eq!(vec.fragments().len(), 2);
70        assert_eq!(vec.capacity(), 4 + 4);
71
72        vec.push(4);
73        assert_eq!(vec.fragments().len(), 3);
74        assert_eq!(vec.capacity(), 4 + 4 + 8);
75
76        assert_eq!(vec, &[0, 1, 2, 3, 4]);
77    }
78
79    #[test]
80    fn append_full_fragment_when_non_empty() {
81        let mut vec = SplitVec::with_recursive_growth();
82        vec.push(42);
83        assert_eq!(vec.capacity(), 4);
84
85        vec.append(alloc::vec![0, 1, 2]);
86        assert_eq!(vec.fragments().len(), 2);
87        assert_eq!(vec.capacity(), 4 + 3);
88
89        vec.push(3);
90        assert_eq!(vec.fragments().len(), 3);
91        assert_eq!(vec.capacity(), 4 + 3 + 6);
92
93        assert_eq!(vec, &[42, 0, 1, 2, 3]);
94    }
95
96    #[test]
97    fn append_half_fragment_when_non_empty() {
98        let mut vec = SplitVec::with_recursive_growth();
99        vec.push(42);
100        assert_eq!(vec.capacity(), 4);
101
102        let mut append = alloc::vec::Vec::with_capacity(4);
103        append.extend_from_slice(&[0, 1, 2]);
104        vec.append(append);
105        assert_eq!(vec.fragments().len(), 2);
106        assert_eq!(vec.capacity(), 4 + 4);
107
108        vec.push(3);
109        assert_eq!(vec.fragments().len(), 2);
110        assert_eq!(vec.capacity(), 4 + 4);
111
112        vec.push(4);
113        assert_eq!(vec.fragments().len(), 3);
114        assert_eq!(vec.capacity(), 4 + 4 + 8);
115
116        assert_eq!(vec, &[42, 0, 1, 2, 3, 4]);
117    }
118}