1use std::{
5 ops::{Index, IndexMut},
6 slice,
7};
8
9struct Chunk<T> {
10 elements: Vec<T>,
12}
13
14impl<T> Chunk<T> {
15 fn with_capacity(capacity: usize) -> Self {
16 let elements = Vec::with_capacity(capacity);
17 assert_eq!(elements.capacity(), capacity);
18 Self { elements }
19 }
20
21 fn len(&self) -> usize {
22 self.elements.len()
23 }
24
25 fn available(&self) -> usize {
27 self.elements.capacity() - self.elements.len()
28 }
29
30 pub fn get(&self, index: usize) -> Option<&T> {
36 self.elements.get(index)
37 }
38
39 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
45 self.elements.get_mut(index)
46 }
47
48 pub fn push(&mut self, new_value: T) {
56 if self.available() == 0 {
57 panic!("No available elements.")
58 }
59 self.elements.push(new_value);
60 }
61
62 pub fn push_get(&mut self, new_value: T) -> &mut T {
63 self.push(new_value);
64 unsafe {
65 let last = self.elements.len() - 1;
66 self.elements.get_unchecked_mut(last)
67 }
68 }
69
70 pub fn iter(&self) -> slice::Iter<T> {
72 self.elements.iter()
73 }
74
75 pub fn iter_mut(&mut self) -> slice::IterMut<T> {
77 self.elements.iter_mut()
78 }
79}
80
81impl<T> Index<usize> for Chunk<T> {
82 type Output = T;
83
84 fn index(&self, index: usize) -> &Self::Output {
85 self.get(index).expect("index out of bounds")
86 }
87}
88
89impl<T> IndexMut<usize> for Chunk<T> {
90 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
91 self.get_mut(index).expect("index out of bounds")
92 }
93}
94
95pub struct ChunkyVec<T> {
99 chunks: Vec<Chunk<T>>,
101}
102
103impl<T> Default for ChunkyVec<T> {
104 fn default() -> Self {
105 Self {
106 chunks: Vec::default(),
107 }
108 }
109}
110
111impl<T> Unpin for ChunkyVec<T> {}
112
113impl<T> ChunkyVec<T> {
114 const DEFAULT_CAPACITY: usize = 32;
115
116 pub fn len(&self) -> usize {
117 if self.chunks.is_empty() {
118 0
119 } else {
120 (self.chunks.len() - 1) * Self::DEFAULT_CAPACITY + self.chunks.last().unwrap().len()
122 }
123 }
124
125 pub fn is_empty(&self) -> bool {
126 self.chunks.is_empty()
128 }
129
130 pub fn iter(&self) -> Iter<T> {
132 Iter::new(self)
133 }
134
135 pub fn iter_mut(&mut self) -> IterMut<T> {
137 IterMut::new(self)
138 }
139
140 pub fn get(&self, index: usize) -> Option<&T> {
142 let (x, y) = (
143 index / Self::DEFAULT_CAPACITY,
144 index % Self::DEFAULT_CAPACITY,
145 );
146 self.chunks.get(x).and_then(|chunk| chunk.get(y))
147 }
148
149 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
151 let (x, y) = (
152 index / Self::DEFAULT_CAPACITY,
153 index % Self::DEFAULT_CAPACITY,
154 );
155 self.chunks.get_mut(x).and_then(|chunk| chunk.get_mut(y))
156 }
157
158 pub fn push(&mut self, new_value: T) {
165 self.push_get(new_value);
166 }
167
168 pub fn push_get(&mut self, new_value: T) -> &mut T {
169 if self.chunks.last().map(Chunk::available).unwrap_or_default() == 0 {
170 self.chunks.push(Chunk::with_capacity(Self::DEFAULT_CAPACITY));
171 }
172 unsafe {
174 let last = self.chunks.len() - 1;
175 self.chunks.get_unchecked_mut(last).push_get(new_value)
176 }
177 }
178}
179
180impl<T> Index<usize> for ChunkyVec<T> {
181 type Output = T;
182
183 fn index(&self, index: usize) -> &Self::Output {
184 self.get(index).expect("index out of bounds")
185 }
186}
187
188impl<T> IndexMut<usize> for ChunkyVec<T> {
189 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
190 self.get_mut(index).expect("index out of bounds")
191 }
192}
193
194#[derive(Clone)]
196pub struct Iter<'a, T> {
197 chunks: slice::Iter<'a, Chunk<T>>,
199 iter: Option<slice::Iter<'a, T>>,
201 len: usize,
203}
204
205impl<'a, T> Iter<'a, T> {
206 pub(crate) fn new(vec: &'a ChunkyVec<T>) -> Self {
208 let len = vec.len();
209 Self {
210 chunks: vec.chunks.iter(),
211 iter: None,
212 len,
213 }
214 }
215}
216
217impl<'a, T> Iterator for Iter<'a, T> {
218 type Item = &'a T;
219
220 fn next(&mut self) -> Option<Self::Item> {
221 loop {
222 if let Some(ref mut iter) = self.iter {
223 if let front @ Some(_) = iter.next() {
224 self.len -= 1;
225 return front;
226 }
227 }
228 self.iter = Some(self.chunks.next()?.iter());
229 }
230 }
231
232 fn size_hint(&self) -> (usize, Option<usize>) {
233 (self.len(), Some(self.len()))
234 }
235}
236
237impl<'a, T> ExactSizeIterator for Iter<'a, T> {
238 fn len(&self) -> usize {
239 self.len
240 }
241}
242
243pub struct IterMut<'a, T> {
245 chunks: slice::IterMut<'a, Chunk<T>>,
247 iter: Option<slice::IterMut<'a, T>>,
249 len: usize,
251}
252
253impl<'a, T> IterMut<'a, T> {
254 pub(crate) fn new(vec: &'a mut ChunkyVec<T>) -> Self {
256 let len = vec.len();
257 Self {
258 chunks: vec.chunks.iter_mut(),
259 iter: None,
260 len,
261 }
262 }
263}
264
265impl<'a, T> Iterator for IterMut<'a, T> {
266 type Item = &'a mut T;
267
268 fn next(&mut self) -> Option<Self::Item> {
269 loop {
270 if let Some(ref mut iter) = self.iter {
271 if let front @ Some(_) = iter.next() {
272 self.len -= 1;
273 return front;
274 }
275 }
276 self.iter = Some(self.chunks.next()?.iter_mut());
277 }
278 }
279
280 fn size_hint(&self) -> (usize, Option<usize>) {
281 (self.len(), Some(self.len()))
282 }
283}
284
285impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
286 fn len(&self) -> usize {
287 self.len
288 }
289}
290impl<'a, T> IntoIterator for &'a ChunkyVec<T> {
291 type Item = &'a T;
292 type IntoIter = Iter<'a, T>;
293
294 fn into_iter(self) -> Iter<'a, T> {
295 self.iter()
296 }
297}
298
299impl<'a, T> IntoIterator for &'a mut ChunkyVec<T> {
300 type Item = &'a mut T;
301 type IntoIter = IterMut<'a, T>;
302
303 fn into_iter(self) -> IterMut<'a, T> {
304 self.iter_mut()
305 }
306}
307
308#[cfg(test)]
309mod tests {
310 use super::*;
311
312 #[test]
313 fn iterate_empty() {
314 let v = ChunkyVec::<usize>::default();
315 for i in &v {
316 println!("{:?}", i);
317 }
318 }
319
320 #[test]
321 fn iterate_multiple_chunks() {
322 let mut v = ChunkyVec::<usize>::default();
323 for i in 0..33 {
324 v.push(i);
325 }
326 let mut iter = v.iter();
327 for _ in 0..32 {
328 iter.next();
329 }
330 assert_eq!(iter.next(), Some(&32));
331 assert_eq!(iter.next(), None);
332 }
333
334 #[test]
335 fn index_multiple_chunks() {
336 let mut v = ChunkyVec::<usize>::default();
337 for i in 0..33 {
338 v.push(i);
339 }
340 assert_eq!(v.get(32), Some(&32));
341 assert_eq!(v[32], 32);
342 }
343}