nexum/auto_expand_vector/
vector.rs

1use std::ops::Range;
2
3/// A vector that automatically expands to fit new elements.
4pub struct AutoExpandVector<T> {
5    pub(super) data: Vec<Option<T>>,
6}
7
8// Creation methods
9impl<T> AutoExpandVector<T> {
10    /// Creates a new [`AutoExpandVector<T>`].
11    pub fn new() -> Self {
12        Self {
13            data: Vec::with_capacity(0),
14        }
15    }
16
17    /// Creates a new [`AutoExpandVector<T>`] with the given capacity.
18    pub fn with_capacity(capacity: usize) -> Self {
19        Self {
20            data: Vec::with_capacity(capacity),
21        }
22    }
23}
24
25// Query methods
26impl<T> AutoExpandVector<T> {
27    /// Returns the capacity of this [`AutoExpandVector<T>`].
28    pub fn capacity(&self) -> usize {
29        self.data.capacity()
30    }
31
32    /// Returns the length of this [`AutoExpandVector<T>`].
33    pub fn len(&self) -> usize {
34        self.data.len()
35    }
36
37    /// Returns `true` if this [`AutoExpandVector<T>`] is empty.
38    pub fn is_empty(&self) -> bool {
39        self.data.len() == 0
40    }
41
42    /// Clears this [`AutoExpandVector<T>`].
43    pub fn clear(&mut self) {
44        self.data.clear();
45        self.data.shrink_to_fit();
46    }
47
48    /// Returns a reference to the element at the given index.
49    pub fn get(&self, index: usize) -> &Option<T> {
50        if index >= self.len() {
51            return &None;
52        }
53
54        &self.data[index]
55    }
56}
57
58// Mutation methods
59impl<T> AutoExpandVector<T> {
60    /// Pushes an element into this [`AutoExpandVector<T>`].
61    pub fn push(&mut self, element: T) {
62        self.data.push(Some(element));
63        self.trim_to_length();
64    }
65
66    /// Inserts an element into this [`AutoExpandVector<T>`] at the given index.
67    pub fn insert(&mut self, index: usize, element: T) {
68        self.fill_with_none(index);
69        self.data.insert(index, Some(element));
70        self.trim_to_length();
71    }
72
73    /// Set the element at the given index to the given element.
74    pub fn set(&mut self, index: usize, element: T) -> Option<T> {
75        if index >= self.len() {
76            self.insert(index, element);
77            return None;
78        }
79
80        let temp = self.data[index].take();
81        self.data[index] = Some(element);
82        self.trim_to_length();
83        temp
84    }
85
86    pub fn remove(&mut self, index: usize) -> Option<T> {
87        let temp = self.data.remove(index);
88        self.trim_to_length();
89        temp
90    }
91
92    pub fn remove_range(&mut self, range: Range<usize>) {
93        self.data.drain(range);
94        self.trim_to_length();
95    }
96}
97
98// Utility methods
99impl<T> AutoExpandVector<T> {
100    /// Fills this [`AutoExpandVector<T>`] with `None` elements until the given index is reached.
101    fn fill_with_none(&mut self, index: usize) {
102        while index >= self.len() {
103            self.data.push(None);
104        }
105    }
106
107    // TODO: Improve performance
108    /// Removes all `None` elements from the start and end of this [`AutoExpandVector<T>`].
109    fn trim_to_length(&mut self) {
110        while let Some(None) = self.data.first() {
111            self.data.remove(0);
112        }
113
114        while let Some(None) = self.data.last() {
115            self.data.pop();
116        }
117
118        self.data.shrink_to_fit();
119    }
120}
121
122impl<T: PartialEq> AutoExpandVector<T> {
123    /// Removes the first element that is equal to the given element.
124    pub fn remove_element(&mut self, element: T) -> bool {
125        let element = &Some(element);
126        let index = self.data.iter().position(|e| e == element);
127
128        if index.is_none() {
129            return false;
130        }
131
132        self.remove(index.unwrap());
133        self.trim_to_length();
134        true
135    }
136}
137
138impl<T: Copy> AutoExpandVector<T> {
139    /// Pushes all elements from a slice into this [`AutoExpandVector<T>`].
140    pub fn push_all(&mut self, elements: &[T]) {
141        for element in elements {
142            self.push(*element);
143        }
144
145        self.trim_to_length();
146    }
147
148    /// Inserts all elements from a slice into this [`AutoExpandVector<T>`] at the given index.
149    pub fn insert_all(&mut self, index: usize, elements: &[T]) {
150        self.fill_with_none(index);
151
152        for element in elements {
153            self.data.insert(index, Some(*element));
154        }
155
156        self.trim_to_length();
157    }
158}
159
160impl<T> Default for AutoExpandVector<T> {
161    /// Creates a new [`AutoExpandVector<T>`] with a capacity of 0.
162    fn default() -> Self {
163        Self::new()
164    }
165}