1use std::{
9 alloc::Layout,
10 fmt,
11 hash::{Hash, Hasher},
12 marker::PhantomData,
13 mem::ManuallyDrop,
14 ops::{Deref, DerefMut},
15 ptr::{self, NonNull},
16};
17
18use allocator_api2::alloc::Allocator;
19use bumpalo::{Bump, boxed::Box as BumpBox};
20
21pub struct BumpVec<'a, T> {
30 ptr: NonNull<T>,
32 cap: usize,
33 len: usize,
34 _marker: PhantomData<&'a ()>,
36}
37
38unsafe impl<T: Send> Send for BumpVec<'_, T> {}
41unsafe impl<T: Sync> Sync for BumpVec<'_, T> {}
42
43impl<T> Default for BumpVec<'_, T> {
44 fn default() -> Self {
45 Self::new()
46 }
47}
48
49impl<'a, T> From<BumpBox<'a, [T]>> for BumpVec<'a, T> {
50 fn from(boxed: BumpBox<'a, [T]>) -> Self {
51 let len = boxed.len();
52 let ptr = BumpBox::into_raw(boxed) as *mut T;
53 Self {
54 ptr: NonNull::new(ptr).unwrap_or(NonNull::dangling()),
55 cap: len,
56 len,
57 _marker: PhantomData,
58 }
59 }
60}
61
62impl<'a, T> BumpVec<'a, T> {
63 pub fn new() -> Self {
64 Self {
65 ptr: NonNull::dangling(),
66 cap: 0,
67 len: 0,
68 _marker: PhantomData,
69 }
70 }
71
72 fn alloc_uninitialized(bump: &'a Bump, cap: usize) -> NonNull<T> {
75 if cap == 0 {
76 return NonNull::dangling();
77 }
78 let layout = Layout::array::<T>(cap).expect("capacity overflow");
79 bump.allocate(layout)
80 .expect("bump allocation failed")
81 .cast::<T>()
82 }
83
84 pub fn with_capacity_in(bump: &'a Bump, capacity: usize) -> Self {
85 Self {
86 ptr: Self::alloc_uninitialized(bump, capacity),
87 cap: capacity,
88 len: 0,
89 _marker: PhantomData,
90 }
91 }
92
93 pub fn from_iter_in(bump: &'a Bump, iter: impl IntoIterator<Item = T>) -> Self {
95 let iter = iter.into_iter();
96 let mut vec =
97 Self::with_capacity_in(bump, iter.size_hint().1.unwrap_or(iter.size_hint().0));
98 vec.extend(bump, iter);
99 vec
100 }
101
102 pub fn into_boxed_slice(self) -> BumpBox<'a, [T]> {
104 let me = ManuallyDrop::new(self);
105 let slice = ptr::slice_from_raw_parts_mut(me.ptr.as_ptr(), me.len);
106 unsafe { BumpBox::from_raw(slice) }
109 }
110
111 unsafe fn realloc_to(&mut self, bump: &'a Bump, new_cap: usize) {
115 debug_assert!(new_cap >= self.len);
116 let new_layout = Layout::array::<T>(new_cap).expect("capacity overflow");
117 let new_ptr = if self.cap == 0 {
118 bump.allocate(new_layout)
120 } else {
121 let old_layout = Layout::array::<T>(self.cap).expect("capacity overflow");
122 unsafe { bump.grow(self.ptr.cast::<u8>(), old_layout, new_layout) }
135 }
136 .expect("bump allocation failed")
137 .cast::<T>();
138 self.ptr = new_ptr;
139 self.cap = new_cap;
140 }
141
142 pub fn push(&mut self, bump: &'a Bump, value: T) {
143 if self.len == self.cap {
144 unsafe { self.realloc_to(bump, if self.cap == 0 { 4 } else { self.cap * 2 }) };
145 }
146 unsafe { self.ptr.as_ptr().add(self.len).write(value) };
148 self.len += 1;
149 }
150
151 pub fn reserve(&mut self, bump: &'a Bump, additional: usize) {
154 let required = self.len + additional;
155 if required > self.cap {
156 unsafe { self.realloc_to(bump, required.max(self.cap * 2)) };
157 }
158 }
159
160 pub fn extend(&mut self, bump: &'a Bump, iter: impl IntoIterator<Item = T>) {
161 let iter = iter.into_iter();
162 self.reserve(bump, iter.size_hint().1.unwrap_or(iter.size_hint().0));
165 for value in iter {
166 self.push(bump, value);
167 }
168 }
169
170 pub fn extend_from_slice(&mut self, bump: &'a Bump, other: &[T])
172 where
173 T: Clone,
174 {
175 self.reserve(bump, other.len());
176 for value in other {
177 unsafe { self.ptr.as_ptr().add(self.len).write(value.clone()) };
180 self.len += 1;
181 }
182 }
183
184 pub fn pop(&mut self) -> Option<T> {
185 if self.len == 0 {
186 return None;
187 }
188 self.len -= 1;
189 Some(unsafe { self.ptr.as_ptr().add(self.len).read() })
191 }
192
193 pub fn swap_remove(&mut self, index: usize) -> T {
196 assert!(index < self.len, "swap_remove index out of bounds");
197 let last = self.pop().unwrap();
199 if index < self.len {
200 std::mem::replace(&mut self[index], last)
201 } else {
202 last
203 }
204 }
205
206 pub fn split_off(&mut self, bump: &'a Bump, at: usize) -> Self {
209 assert!(at <= self.len, "split_off index out of bounds");
210 let tail_len = self.len - at;
211 let mut tail = Self::with_capacity_in(bump, tail_len);
212 unsafe {
215 ptr::copy_nonoverlapping(self.ptr.as_ptr().add(at), tail.ptr.as_ptr(), tail_len);
216 }
217 tail.len = tail_len;
218 self.len = at;
219 tail
220 }
221}
222
223impl<T> Deref for BumpVec<'_, T> {
224 type Target = [T];
225 fn deref(&self) -> &[T] {
226 unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
229 }
230}
231
232impl<T> DerefMut for BumpVec<'_, T> {
233 fn deref_mut(&mut self) -> &mut [T] {
234 unsafe { std::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
236 }
237}
238
239impl<T> Drop for BumpVec<'_, T> {
240 fn drop(&mut self) {
241 unsafe { ptr::drop_in_place(&mut **self) }
243 }
244}
245
246impl<'a, T> IntoIterator for BumpVec<'a, T> {
247 type Item = T;
248 type IntoIter = IntoIter<'a, T>;
249 fn into_iter(self) -> IntoIter<'a, T> {
250 let me = ManuallyDrop::new(self);
252 IntoIter {
253 ptr: me.ptr,
254 len: me.len,
255 idx: 0,
256 _marker: PhantomData,
257 }
258 }
259}
260
261impl<'b, T> IntoIterator for &'b BumpVec<'_, T> {
262 type Item = &'b T;
263 type IntoIter = std::slice::Iter<'b, T>;
264 fn into_iter(self) -> Self::IntoIter {
265 self.iter()
266 }
267}
268
269impl<'b, T> IntoIterator for &'b mut BumpVec<'_, T> {
270 type Item = &'b mut T;
271 type IntoIter = std::slice::IterMut<'b, T>;
272 fn into_iter(self) -> Self::IntoIter {
273 self.iter_mut()
274 }
275}
276
277impl<T: PartialEq> PartialEq for BumpVec<'_, T> {
278 fn eq(&self, other: &Self) -> bool {
279 **self == **other
280 }
281}
282impl<T: Eq> Eq for BumpVec<'_, T> {}
283impl<T: Hash> Hash for BumpVec<'_, T> {
284 fn hash<H: Hasher>(&self, state: &mut H) {
285 (**self).hash(state)
286 }
287}
288impl<T: fmt::Debug> fmt::Debug for BumpVec<'_, T> {
289 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
290 fmt::Debug::fmt(&**self, f)
291 }
292}
293
294pub struct IntoIter<'a, T> {
297 ptr: NonNull<T>,
298 len: usize,
299 idx: usize,
300 _marker: PhantomData<&'a ()>,
301}
302
303unsafe impl<T: Send> Send for IntoIter<'_, T> {}
305unsafe impl<T: Sync> Sync for IntoIter<'_, T> {}
306
307impl<T> Iterator for IntoIter<'_, T> {
308 type Item = T;
309 fn next(&mut self) -> Option<T> {
310 if self.idx == self.len {
311 return None;
312 }
313 let value = unsafe { self.ptr.as_ptr().add(self.idx).read() };
315 self.idx += 1;
316 Some(value)
317 }
318
319 fn size_hint(&self) -> (usize, Option<usize>) {
320 let remaining = self.len - self.idx;
321 (remaining, Some(remaining))
322 }
323}
324
325impl<T> DoubleEndedIterator for IntoIter<'_, T> {
326 fn next_back(&mut self) -> Option<T> {
327 if self.idx == self.len {
328 return None;
329 }
330 self.len -= 1;
331 Some(unsafe { self.ptr.as_ptr().add(self.len).read() })
333 }
334}
335
336impl<T> ExactSizeIterator for IntoIter<'_, T> {}
337
338impl<T> Drop for IntoIter<'_, T> {
339 fn drop(&mut self) {
340 unsafe {
342 ptr::drop_in_place(std::ptr::slice_from_raw_parts_mut(
343 self.ptr.as_ptr().add(self.idx),
344 self.len - self.idx,
345 ));
346 }
347 }
348}
349
350#[cfg(test)]
351mod tests {
352 use std::{
353 cell::Cell,
354 collections::hash_map::DefaultHasher,
355 hash::{Hash, Hasher},
356 rc::Rc,
357 };
358
359 use bumpalo::Bump;
360
361 use super::BumpVec;
362
363 #[test]
364 fn push_grows_and_indexes() {
365 let bump = Bump::new();
366 let mut v = BumpVec::new();
367 assert!(v.is_empty());
368 for i in 0..100 {
370 v.push(&bump, i);
371 }
372 assert_eq!(v.len(), 100);
373 assert_eq!(&*v, &(0..100).collect::<Vec<_>>()[..]);
374 assert_eq!(v[42], 42);
375 }
376
377 #[test]
378 fn with_capacity_extend_and_from_iter() {
379 let bump = Bump::new();
380 let mut v = BumpVec::with_capacity_in(&bump, 4);
381 assert!(v.is_empty());
382 v.extend(&bump, [1, 2, 3]);
383 assert_eq!(&*v, &[1, 2, 3][..]);
384
385 let v2 = BumpVec::from_iter_in(&bump, [10, 20, 30, 40]);
386 assert_eq!(&*v2, &[10, 20, 30, 40][..]);
387 }
388
389 #[test]
390 fn extend_from_slice() {
391 let bump = Bump::new();
392 let mut v = BumpVec::from_iter_in(&bump, [1, 2]);
393 v.extend_from_slice(&bump, &[3, 4, 5]);
395 assert_eq!(&*v, &[1, 2, 3, 4, 5][..]);
396 v.extend_from_slice(&bump, &[]);
398 assert_eq!(&*v, &[1, 2, 3, 4, 5][..]);
399 let mut empty = BumpVec::new();
401 empty.extend_from_slice(&bump, &[7, 8, 9]);
402 assert_eq!(&*empty, &[7, 8, 9][..]);
403 }
404
405 #[test]
410 fn grow_across_separate_bumps() {
411 let bump1 = Bump::new();
412 let bump2 = Bump::new();
413
414 let mut v = BumpVec::with_capacity_in(&bump1, 2);
416 v.push(&bump1, 1);
417 v.push(&bump1, 2);
418
419 v.push(&bump2, 3);
422 v.push(&bump2, 4);
423 v.push(&bump2, 5);
424 assert_eq!(&*v, &[1, 2, 3, 4, 5][..]);
425
426 v.extend(&bump2, 6..=10);
428 assert_eq!(&*v, &(1..=10).collect::<Vec<_>>()[..]);
429 }
430
431 #[test]
434 fn grow_across_separate_bumps_does_not_drop_during_move() {
435 let bump1 = Bump::new();
436 let bump2 = Bump::new();
437 let counter = Rc::new(Cell::new(0));
438
439 let mut v = BumpVec::with_capacity_in(&bump1, 2);
440 v.push(&bump1, DropCounter(counter.clone()));
441 v.push(&bump1, DropCounter(counter.clone()));
442 v.push(&bump2, DropCounter(counter.clone()));
444 assert_eq!(counter.get(), 0);
445
446 drop(v);
447 assert_eq!(counter.get(), 3);
448 }
449
450 #[test]
451 fn pop() {
452 let bump = Bump::new();
453 let mut v = BumpVec::from_iter_in(&bump, [1, 2, 3]);
454 assert_eq!(v.pop(), Some(3));
455 assert_eq!(v.pop(), Some(2));
456 assert_eq!(v.pop(), Some(1));
457 assert_eq!(v.pop(), None);
458 assert!(v.is_empty());
459 }
460
461 #[test]
462 fn swap_remove() {
463 let bump = Bump::new();
464 let mut v = BumpVec::from_iter_in(&bump, [1, 2, 3, 4, 5]);
465 assert_eq!(v.swap_remove(1), 2);
467 assert_eq!(&*v, &[1, 5, 3, 4][..]);
468 assert_eq!(v.swap_remove(3), 4);
470 assert_eq!(&*v, &[1, 5, 3][..]);
471 assert_eq!(v.swap_remove(0), 1);
473 assert_eq!(&*v, &[3, 5][..]);
474 }
475
476 #[test]
477 #[should_panic(expected = "swap_remove index out of bounds")]
478 fn swap_remove_out_of_bounds() {
479 let bump = Bump::new();
480 let mut v = BumpVec::from_iter_in(&bump, [1, 2, 3]);
481 v.swap_remove(3);
482 }
483
484 #[test]
485 fn swap_remove_does_not_double_free() {
486 let bump = Bump::new();
487 let counter = Rc::new(Cell::new(0));
488 let mut v = BumpVec::new();
489 for _ in 0..3 {
490 v.push(&bump, DropCounter(counter.clone()));
491 }
492 let removed = v.swap_remove(0);
493 drop(removed);
494 assert_eq!(counter.get(), 1);
495 drop(v);
497 assert_eq!(counter.get(), 3);
498 }
499
500 #[test]
501 fn split_off_prefix_and_suffix() {
502 let bump = Bump::new();
503 let mut v = BumpVec::from_iter_in(&bump, [1, 2, 3, 4, 5]);
504 let tail = v.split_off(&bump, 2);
505 assert_eq!(&*v, &[1, 2][..]);
506 assert_eq!(&*tail, &[3, 4, 5][..]);
507
508 let mut v = BumpVec::from_iter_in(&bump, [1, 2]);
510 let tail = v.split_off(&bump, 2);
511 assert_eq!(&*v, &[1, 2][..]);
512 assert!(tail.is_empty());
513
514 let mut v = BumpVec::from_iter_in(&bump, [1, 2]);
516 let tail = v.split_off(&bump, 0);
517 assert!(v.is_empty());
518 assert_eq!(&*tail, &[1, 2][..]);
519 }
520
521 #[test]
522 fn iterates_by_ref_mut_and_value() {
523 let bump = Bump::new();
524 let mut v = BumpVec::from_iter_in(&bump, [1, 2, 3]);
525
526 let sum: i32 = (&v).into_iter().copied().sum();
527 assert_eq!(sum, 6);
528
529 for x in &mut v {
530 *x *= 2;
531 }
532 assert_eq!(&*v, &[2, 4, 6][..]);
533
534 let collected: Vec<i32> = v.into_iter().collect();
535 assert_eq!(collected, vec![2, 4, 6]);
536 }
537
538 #[test]
539 fn into_iter_double_ended() {
540 let bump = Bump::new();
541 let v = BumpVec::from_iter_in(&bump, [1, 2, 3, 4]);
542 let reversed: Vec<i32> = v.into_iter().rev().collect();
543 assert_eq!(reversed, vec![4, 3, 2, 1]);
544
545 let v = BumpVec::from_iter_in(&bump, [1, 2, 3]);
547 let mut it = v.into_iter();
548 assert_eq!(it.next(), Some(1));
549 assert_eq!(it.next_back(), Some(3));
550 assert_eq!(it.next(), Some(2));
551 assert_eq!(it.next_back(), None);
552 assert_eq!(it.next(), None);
553 }
554
555 #[test]
556 fn double_ended_drops_remainder_once() {
557 let bump = Bump::new();
558 let counter = Rc::new(Cell::new(0));
559 let mut v = BumpVec::new();
560 for _ in 0..5 {
561 v.push(&bump, DropCounter(counter.clone()));
562 }
563 let mut it = v.into_iter();
564 drop(it.next()); drop(it.next_back()); assert_eq!(counter.get(), 2);
567 drop(it); assert_eq!(counter.get(), 5);
569 }
570
571 #[test]
572 fn eq_hash_and_debug() {
573 let bump = Bump::new();
574 let a = BumpVec::from_iter_in(&bump, [1, 2, 3]);
575 let b = BumpVec::from_iter_in(&bump, [1, 2, 3]);
576 let c = BumpVec::from_iter_in(&bump, [1, 2]);
577 assert_eq!(a, b);
578 assert_ne!(a, c);
579 assert_eq!(format!("{a:?}"), "[1, 2, 3]");
580
581 let mut ha = DefaultHasher::new();
582 let mut hb = DefaultHasher::new();
583 a.hash(&mut ha);
584 b.hash(&mut hb);
585 assert_eq!(ha.finish(), hb.finish());
586 }
587
588 struct DropCounter(Rc<Cell<usize>>);
591 impl Drop for DropCounter {
592 fn drop(&mut self) {
593 self.0.set(self.0.get() + 1);
594 }
595 }
596
597 #[test]
598 fn drops_each_element_exactly_once() {
599 let bump = Bump::new();
600 let counter = Rc::new(Cell::new(0));
601 {
602 let mut v = BumpVec::new();
603 for _ in 0..10 {
604 v.push(&bump, DropCounter(counter.clone()));
605 }
606 assert_eq!(counter.get(), 0);
608 }
609 assert_eq!(counter.get(), 10);
610 }
611
612 #[test]
613 fn into_iter_drops_unconsumed_remainder() {
614 let bump = Bump::new();
615 let counter = Rc::new(Cell::new(0));
616 let mut v = BumpVec::new();
617 for _ in 0..5 {
618 v.push(&bump, DropCounter(counter.clone()));
619 }
620 let mut iter = v.into_iter();
621 drop(iter.next());
622 drop(iter.next());
623 assert_eq!(counter.get(), 2);
624 drop(iter); assert_eq!(counter.get(), 5);
626 }
627
628 #[test]
629 fn pop_does_not_double_free() {
630 let bump = Bump::new();
631 let counter = Rc::new(Cell::new(0));
632 let mut v = BumpVec::new();
633 for _ in 0..3 {
634 v.push(&bump, DropCounter(counter.clone()));
635 }
636 let popped = v.pop().unwrap();
637 drop(popped);
638 assert_eq!(counter.get(), 1);
639 drop(v);
641 assert_eq!(counter.get(), 3);
642 }
643}