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}