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    /// use orx_pseudo_default::PseudoDefault;
36    ///
37    /// #[derive(Clone)]
38    /// pub struct DoubleEverySecondFragment(usize); // any custom growth strategy
39    ///
40    /// impl PseudoDefault for DoubleEverySecondFragment {
41    ///     fn pseudo_default() -> Self {
42    ///         DoubleEverySecondFragment(1)
43    ///     }
44    /// }
45    ///
46    /// impl Growth for DoubleEverySecondFragment {
47    ///     fn new_fragment_capacity_from(&self, fragment_capacities: impl ExactSizeIterator<Item = usize>) -> usize {
48    ///         let num_fragments = fragment_capacities.len();
49    ///         fragment_capacities
50    ///             .last()
51    ///             .map(|f| {
52    ///                 let do_double = num_fragments % 2 == 0;
53    ///                 if do_double {
54    ///                     f * 2
55    ///                 } else {
56    ///                     f
57    ///                 }
58    ///             })
59    ///             .unwrap_or(self.0)
60    ///     }
61    /// }
62    /// let mut vec = SplitVec::with_growth(DoubleEverySecondFragment(8));
63    /// for i in 0..17 {
64    ///     vec.push(i);
65    /// }
66    ///
67    /// assert_eq!(3, vec.fragments().len());
68    ///
69    /// assert_eq!(8, vec.fragments()[0].capacity());
70    /// assert_eq!(8, vec.fragments()[0].len());
71    ///
72    /// assert_eq!(8, vec.fragments()[1].capacity());
73    /// assert_eq!(8, vec.fragments()[1].len());
74    ///
75    /// assert_eq!(16, vec.fragments()[2].capacity());
76    /// assert_eq!(1, vec.fragments()[2].len());
77    /// ```
78    pub fn with_growth(growth: G) -> Self {
79        let capacity = Growth::new_fragment_capacity::<T>(&growth, &[]);
80        let fragment = Fragment::new(capacity);
81        let fragments = alloc::vec![fragment];
82        SplitVec::from_raw_parts(0, fragments, growth)
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89    use crate::{Doubling, Linear};
90
91    #[test]
92    fn new() {
93        let vec: SplitVec<usize> = SplitVec::new();
94        let vec: SplitVec<usize, Doubling> = vec;
95
96        assert_eq!(1, vec.fragments().len());
97        assert_eq!(4, vec.fragments()[0].capacity());
98    }
99
100    #[test]
101    fn with_initial_capacity() {
102        let vec: SplitVec<usize> = SplitVec::new();
103        let vec: SplitVec<usize, Doubling> = vec;
104
105        assert_eq!(1, vec.fragments().len());
106        assert_eq!(4, vec.fragments()[0].capacity());
107    }
108
109    #[test]
110    fn with_growth() {
111        let vec: SplitVec<char, Linear> = SplitVec::with_growth(Linear::new(3));
112        assert_eq!(1, vec.fragments().len());
113        assert_eq!(8, vec.fragments()[0].capacity());
114
115        let vec: SplitVec<char, Doubling> = SplitVec::with_growth(Doubling);
116        assert_eq!(1, vec.fragments().len());
117        assert_eq!(4, vec.fragments()[0].capacity());
118    }
119}