1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
use crate::{Fragment, SplitVec};

impl<T> SplitVec<T> {
    /// Returns the number of elements in the vector, also referred to
    /// as its 'length'.
    ///
    /// # Examples
    ///
    /// ```
    /// use orx_split_vec::SplitVec;
    ///
    /// let mut vec = SplitVec::default();
    /// assert_eq!(0, vec.len());
    /// vec.push(1);
    /// vec.push(2);
    /// vec.push(3);
    /// assert_eq!(3, vec.len());
    /// ```
    pub fn len(&self) -> usize {
        self.fragments.iter().map(|f| f.len()).sum()
    }
    /// Returns `true` if the vector contains no elements.
    ///
    /// # Examples
    ///
    /// ```
    /// use orx_split_vec::SplitVec;
    ///
    /// let mut vec = SplitVec::default();
    /// assert!(vec.is_empty());
    /// vec.push(1);
    /// assert!(!vec.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        self.fragments.iter().all(|f| f.is_empty())
    }

    /// Returns the total number of elements the split vector can hold without
    /// reallocating.
    ///
    /// See `FragmentGrowth` for details of capacity growth policies.
    ///
    /// # Examples
    ///
    /// ```
    /// use orx_split_vec::SplitVec;
    ///
    /// // default growth starting with 4, and doubling at each new fragment.
    /// let mut vec = SplitVec::<usize>::default();
    /// assert_eq!(4, vec.capacity());
    ///
    /// for i in 0..4 {
    ///     vec.push(i);
    /// }
    /// assert_eq!(4, vec.capacity());
    ///
    /// vec.push(4);
    /// assert_eq!(4 + 6, vec.capacity());
    ///
    /// // second fragment will have capacity 4*1.5 by default growth
    /// // see `FragmentGrowth` for different growth strategies.
    ///
    /// ```
    pub fn capacity(&self) -> usize {
        self.fragments.iter().map(|f| f.capacity()).sum()
    }

    /// Returns a reference to the element with the given `index`;
    /// None if index is out of bounds.
    ///
    /// # Examples
    ///
    /// ```
    /// use orx_split_vec::SplitVec;
    ///
    /// let mut vec = SplitVec::<usize>::default();
    /// vec.extend_from_slice(&[10, 40, 30]);
    /// assert_eq!(Some(&40), vec.get(1));
    /// assert_eq!(None, vec.get(3));
    /// ```
    pub fn get(&self, index: usize) -> Option<&T> {
        self.fragment_and_inner_index(index)
            .map(|(f, i)| &self.fragments[f][i])
    }
    /// Returns a mutable reference to the element with the given `index`;
    /// None if index is out of bounds.
    ///
    /// # Examples
    ///
    /// ```
    /// use orx_split_vec::SplitVec;
    ///
    /// let mut vec = SplitVec::<usize>::default();
    /// vec.extend_from_slice(&[0, 1, 2]);
    ///
    /// if let Some(elem) = vec.get_mut(1) {
    ///     *elem = 42;
    /// }
    ///
    /// assert_eq!(vec, &[0, 42, 2]);
    /// ```
    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
        self.fragment_and_inner_index(index)
            .map(|(f, i)| &mut self.fragments[f][i])
    }

    /// Directly appends the `fragment` to the end of the split vector.
    ///
    /// This operation does not require any copies or allocation;
    /// the fragment is moved into the split vector and added as a new fragment,
    /// without copying the underlying data.
    ///
    /// # Examples
    ///
    /// ```
    /// use orx_split_vec::SplitVec;
    ///
    /// let mut vec = SplitVec::<usize>::default();
    ///
    /// // append to empty split vector
    /// assert!(vec.is_empty());
    /// let mut other = Vec::with_capacity(4);
    /// other.extend_from_slice(&[0, 1, 2]);
    ///
    /// vec.append(other);
    /// assert_eq!(vec, &[0, 1, 2]);
    /// assert_eq!(1, vec.fragments().len());
    /// assert_eq!(4, vec.fragments()[0].capacity()); // SplitVec will make use of the appended vector's additional capacity
    ///
    /// vec.push(3);
    /// assert_eq!(vec, &[0, 1, 2, 3]);
    /// assert_eq!(1, vec.fragments().len());
    /// assert_eq!(vec.fragments()[0].as_slice(), &[0, 1, 2, 3]);
    ///
    /// // next push will use SplitVec's growth
    /// vec.extend_from_slice(&[4, 5, 6]);
    /// assert_eq!(vec, &[0, 1, 2, 3, 4, 5, 6]);
    /// assert_eq!(2, vec.fragments().len());
    /// assert_eq!(vec.fragments()[0].as_slice(), &[0, 1, 2, 3]);
    /// assert_eq!(vec.fragments()[1].as_slice(), &[4, 5, 6]);
    ///
    /// // we can append another fragment directly
    /// vec.append(vec![7, 8]);
    /// assert_eq!(vec, &[0, 1, 2, 3, 4, 5, 6, 7, 8]);
    /// assert_eq!(3, vec.fragments().len());
    /// assert_eq!(vec.fragments()[0].as_slice(), &[0, 1, 2, 3]);
    /// assert_eq!(vec.fragments()[1].as_slice(), &[4, 5, 6]);
    /// assert_eq!(vec.fragments()[2].as_slice(), &[7, 8]);
    /// ```
    pub fn append<F>(&mut self, fragment: F)
    where
        F: Into<Fragment<T>>,
    {
        if self.is_empty() {
            self.fragments[0] = fragment.into();
        } else {
            self.fragments.push(fragment.into());
        }
    }
}