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}