orx_split_vec/new_split_vec/
new.rs

1use crate::{Fragment, Growth, SplitVec};
2
3impl<T> SplitVec<T> {
4    /// Creates an empty split vector with default growth strategy.
5    ///
6    /// Default growth strategy is `Doubling` with initial capacity of 4.
7    ///
8    /// # Examples
9    ///
10    /// ```
11    /// use orx_split_vec::*;
12    ///
13    /// let vec: SplitVec<f32> = SplitVec::new();
14    ///
15    /// assert_eq!(1, vec.fragments().len());
16    /// assert_eq!(4, vec.fragments()[0].capacity());
17    /// ```
18    pub fn new() -> Self {
19        Self::with_doubling_growth()
20    }
21}
22
23impl<T, G> SplitVec<T, G>
24where
25    G: Growth,
26{
27    /// Creates an empty split vector with the given `growth` strategy.
28    ///
29    /// This constructor is especially useful to define custom growth strategies.
30    ///
31    /// # Examples
32    ///
33    /// ```
34    /// use orx_split_vec::*;
35    ///
36    /// #[derive(Clone)]
37    /// pub struct DoubleEverySecondFragment(usize); // any custom growth strategy
38    ///
39    /// impl PseudoDefault for DoubleEverySecondFragment {
40    ///     fn pseudo_default() -> Self {
41    ///         DoubleEverySecondFragment(1)
42    ///     }
43    /// }
44    ///
45    /// impl Growth for DoubleEverySecondFragment {
46    ///     fn new_fragment_capacity_from(&self, fragment_capacities: impl ExactSizeIterator<Item = usize>) -> usize {
47    ///         let num_fragments = fragment_capacities.len();
48    ///         fragment_capacities
49    ///             .last()
50    ///             .map(|f| {
51    ///                 let do_double = num_fragments % 2 == 0;
52    ///                 if do_double {
53    ///                     f * 2
54    ///                 } else {
55    ///                     f
56    ///                 }
57    ///             })
58    ///             .unwrap_or(self.0)
59    ///     }
60    /// }
61    /// let mut vec = SplitVec::with_growth(DoubleEverySecondFragment(8));
62    /// for i in 0..17 {
63    ///     vec.push(i);
64    /// }
65    ///
66    /// assert_eq!(3, vec.fragments().len());
67    ///
68    /// assert_eq!(8, vec.fragments()[0].capacity());
69    /// assert_eq!(8, vec.fragments()[0].len());
70    ///
71    /// assert_eq!(8, vec.fragments()[1].capacity());
72    /// assert_eq!(8, vec.fragments()[1].len());
73    ///
74    /// assert_eq!(16, vec.fragments()[2].capacity());
75    /// assert_eq!(1, vec.fragments()[2].len());
76    /// ```
77    pub fn with_growth(growth: G) -> Self {
78        let capacity = Growth::new_fragment_capacity::<T>(&growth, &[]);
79        let fragment = Fragment::new(capacity);
80        let fragments = alloc::vec![fragment];
81        SplitVec::from_raw_parts(0, fragments, growth)
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88    use crate::{Doubling, Linear};
89
90    #[test]
91    fn new() {
92        let vec: SplitVec<usize> = SplitVec::new();
93        let vec: SplitVec<usize, Doubling> = vec;
94
95        assert_eq!(1, vec.fragments().len());
96        assert_eq!(4, vec.fragments()[0].capacity());
97    }
98
99    #[test]
100    fn with_initial_capacity() {
101        let vec: SplitVec<usize> = SplitVec::new();
102        let vec: SplitVec<usize, Doubling> = vec;
103
104        assert_eq!(1, vec.fragments().len());
105        assert_eq!(4, vec.fragments()[0].capacity());
106    }
107
108    #[test]
109    fn with_growth() {
110        let vec: SplitVec<char, Linear> = SplitVec::with_growth(Linear::new(3));
111        assert_eq!(1, vec.fragments().len());
112        assert_eq!(8, vec.fragments()[0].capacity());
113
114        let vec: SplitVec<char, Doubling> = SplitVec::with_growth(Doubling);
115        assert_eq!(1, vec.fragments().len());
116        assert_eq!(4, vec.fragments()[0].capacity());
117    }
118}