1use crate::Arena;
2use crate::raw_vec::RawVec;
3use allocator_api2::alloc::Allocator;
4use std::fmt;
5use std::hash::{Hash, Hasher};
6use std::ops::{Deref, DerefMut};
7use std::ptr::NonNull;
8
9#[macro_export]
15macro_rules! vec_in {
16 (in $alloc:expr $(,)?) => { $crate::Vec::new_in($alloc) };
17 (in $alloc:expr; $elem:expr; $n:expr) => {{
18 let n = $n;
19 let mut v = $crate::Vec::with_capacity_in(n, $alloc);
20 for _ in 0..n {
21 v.push(::core::clone::Clone::clone(&$elem));
22 }
23 v
24 }};
25 (in $alloc:expr; $($x:expr),+ $(,)?) => {{
26 let mut v = $crate::Vec::new_in($alloc);
27 $( v.push($x); )+
28 v
29 }};
30}
31
32#[repr(C)]
37pub struct Vec<'a, T, A: Allocator = &'a Arena> {
38 raw: RawVec<T>,
39 alloc: A,
40 marker: std::marker::PhantomData<&'a ()>,
41}
42
43impl<'a, T, A: Allocator> Vec<'a, T, A> {
44 #[inline]
46 pub fn new_in(alloc: A) -> Self {
47 Self { raw: RawVec::new(), alloc, marker: std::marker::PhantomData }
48 }
49
50 #[inline]
52 pub fn with_capacity_in(cap: usize, alloc: A) -> Self {
53 let mut raw = RawVec::new();
54 if cap > 0 {
55 raw.grow(cap as u32, &alloc);
56 }
57 Self { raw, alloc, marker: std::marker::PhantomData }
58 }
59
60 #[inline]
61 pub fn len(&self) -> usize {
62 self.raw.len as usize
63 }
64
65 #[inline]
66 pub fn is_empty(&self) -> bool {
67 self.raw.len == 0
68 }
69
70 #[inline]
71 pub fn capacity(&self) -> usize {
72 self.raw.cap as usize
73 }
74
75 #[inline]
77 pub fn as_slice(&self) -> &[T] {
78 self
79 }
80
81 #[inline]
83 pub fn as_mut_slice(&mut self) -> &mut [T] {
84 self
85 }
86
87 #[inline]
88 fn reserve_one(&mut self) {
89 if self.raw.len == self.raw.cap {
90 self.raw.grow(self.raw.len + 1, &self.alloc);
91 }
92 }
93
94 #[inline]
96 pub fn push(&mut self, value: T) {
97 self.reserve_one();
98 debug_assert!(self.raw.len < self.raw.cap, "reserve_one must guarantee spare capacity");
99 unsafe {
100 self.raw.ptr.as_ptr().add(self.raw.len as usize).write(value);
101 }
102 self.raw.len += 1;
103 }
104
105 #[inline]
107 pub fn pop(&mut self) -> Option<T> {
108 if self.raw.len == 0 {
109 return None;
110 }
111 self.raw.len -= 1;
112 Some(unsafe { self.raw.ptr.as_ptr().add(self.raw.len as usize).read() })
113 }
114
115 pub fn insert(&mut self, index: usize, value: T) {
120 assert!(index as u32 <= self.raw.len, "insertion index out of bounds");
121 self.reserve_one();
122 debug_assert!(self.raw.len < self.raw.cap, "reserve_one must guarantee spare capacity");
123 unsafe {
124 let base = self.raw.ptr.as_ptr();
125 let at = base.add(index);
126 std::ptr::copy(at, at.add(1), (self.raw.len as usize) - index);
127 at.write(value);
128 }
129 self.raw.len += 1;
130 }
131
132 pub fn remove(&mut self, index: usize) -> T {
137 assert!((index as u32) < self.raw.len, "removal index out of bounds");
138 unsafe {
139 let base = self.raw.ptr.as_ptr();
140 let at = base.add(index);
141 let value = at.read();
142 std::ptr::copy(at.add(1), at, (self.raw.len as usize) - index - 1);
143 self.raw.len -= 1;
144 value
145 }
146 }
147
148 #[inline]
150 pub fn truncate(&mut self, len: usize) {
151 if (len as u32) < self.raw.len {
152 self.raw.len = len as u32;
153 }
154 }
155
156 #[inline]
158 pub fn clear(&mut self) {
159 self.raw.len = 0;
160 }
161
162 pub fn retain<F: FnMut(&T) -> bool>(&mut self, mut f: F) {
168 let original_len = self.raw.len;
169 let base = self.raw.ptr.as_ptr();
170 self.raw.len = 0;
171
172 struct Guard<'v, 'a, T, A: Allocator> {
173 v: &'v mut Vec<'a, T, A>,
174 base: *mut T,
175 processed: u32,
176 deleted: u32,
177 original_len: u32,
178 }
179 impl<'v, 'a, T, A: Allocator> Drop for Guard<'v, 'a, T, A> {
180 fn drop(&mut self) {
181 let tail = self.original_len - self.processed;
182 if self.deleted > 0 && tail > 0 {
183 unsafe {
184 std::ptr::copy(
185 self.base.add(self.processed as usize),
186 self.base.add((self.processed - self.deleted) as usize),
187 tail as usize,
188 );
189 }
190 }
191 self.v.raw.len = self.original_len - self.deleted;
192 }
193 }
194
195 let mut g = Guard { v: self, base, processed: 0, deleted: 0, original_len };
196 for read in 0..original_len {
197 let keep = unsafe { f(&*g.base.add(read as usize)) };
198 g.processed = read + 1;
199 if keep {
200 if g.deleted > 0 {
201 unsafe {
202 let src = g.base.add(read as usize);
203 g.base.add((read - g.deleted) as usize).write(src.read());
204 }
205 }
206 } else {
207 unsafe { g.base.add(read as usize).drop_in_place() };
208 g.deleted += 1;
209 }
210 }
211 drop(g);
212 }
213
214 pub fn dedup(&mut self)
216 where
217 T: PartialEq,
218 {
219 if self.raw.len < 2 {
220 return;
221 }
222 let base = self.raw.ptr.as_ptr();
223 let mut write = 1usize;
224 for read in 1..self.raw.len as usize {
225 let duplicate = unsafe { *base.add(read) == *base.add(write - 1) };
228 if duplicate {
229 unsafe { base.add(read).drop_in_place() };
231 continue;
232 }
233 if write != read {
234 unsafe { base.add(write).write(base.add(read).read()) };
236 }
237 write += 1;
238 }
239 self.raw.len = write as u32;
240 }
241
242 pub fn drain<R: std::ops::RangeBounds<u32>>(&mut self, range: R) -> Drain<'_, T> {
248 let len = self.raw.len;
249 let start = match range.start_bound() {
250 std::ops::Bound::Included(&n) => n,
251 std::ops::Bound::Excluded(&n) => n + 1,
252 std::ops::Bound::Unbounded => 0,
253 };
254 let end = match range.end_bound() {
255 std::ops::Bound::Included(&n) => n + 1,
256 std::ops::Bound::Excluded(&n) => n,
257 std::ops::Bound::Unbounded => len,
258 };
259 assert!(start <= end, "drain start must not exceed end");
260 assert!(end <= len, "drain range out of bounds");
261 self.raw.len = start;
262 Drain {
263 ptr: self.raw.ptr.as_ptr(),
264 index: start,
265 end,
266 tail: len,
267 vec_len: NonNull::from(&mut self.raw.len),
268 marker: std::marker::PhantomData,
269 }
270 }
271
272 #[inline]
277 pub fn into_slice(self) -> &'a [T] {
278 unsafe { std::slice::from_raw_parts(self.raw.ptr.as_ptr(), self.raw.len as usize) }
282 }
283}
284
285impl<'a, T: Clone, A: Allocator> Vec<'a, T, A> {
286 pub fn extend_from_slice(&mut self, slice: &[T]) {
288 self.reserve(slice.len());
289 for value in slice {
290 self.push(value.clone());
291 }
292 }
293
294 #[inline]
295 fn reserve(&mut self, additional: usize) {
296 let required = self.raw.len + (additional as u32);
297 if required > self.raw.cap {
298 self.raw.grow(required, &self.alloc);
299 }
300 }
301}
302
303impl<'a, T, A: Allocator> Extend<T> for Vec<'a, T, A> {
304 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
305 let iter = iter.into_iter();
306 let (lower, _) = iter.size_hint();
307 if lower > 0 {
308 let required = self.raw.len + (lower as u32);
309 if required > self.raw.cap {
310 self.raw.grow(required, &self.alloc);
311 }
312 }
313 for value in iter {
314 self.push(value);
315 }
316 }
317}
318
319impl<'a, T, A: Allocator> Deref for Vec<'a, T, A> {
320 type Target = [T];
321
322 #[inline]
323 fn deref(&self) -> &[T] {
324 debug_assert!(self.raw.len <= self.raw.cap, "len must never exceed capacity");
325 unsafe { std::slice::from_raw_parts(self.raw.ptr.as_ptr(), self.raw.len as usize) }
326 }
327}
328
329impl<'a, T, A: Allocator> DerefMut for Vec<'a, T, A> {
330 #[inline]
331 fn deref_mut(&mut self) -> &mut [T] {
332 debug_assert!(self.raw.len <= self.raw.cap, "len must never exceed capacity");
333 unsafe { std::slice::from_raw_parts_mut(self.raw.ptr.as_ptr(), self.raw.len as usize) }
334 }
335}
336
337impl<'a, T: Clone, A: Allocator + Clone> Clone for Vec<'a, T, A> {
338 fn clone(&self) -> Self {
339 let mut out = Vec::with_capacity_in(self.raw.len as usize, self.alloc.clone());
340 for value in self.iter() {
341 out.push(value.clone());
342 }
343 out
344 }
345}
346
347impl<'a, T: fmt::Debug, A: Allocator> fmt::Debug for Vec<'a, T, A> {
348 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
349 fmt::Debug::fmt(&**self, f)
350 }
351}
352
353impl<'a, T: PartialEq, A: Allocator> PartialEq for Vec<'a, T, A> {
354 fn eq(&self, other: &Self) -> bool {
355 **self == **other
356 }
357}
358
359impl<'a, T: Eq, A: Allocator> Eq for Vec<'a, T, A> {}
360
361impl<'a, T: PartialOrd, A: Allocator> PartialOrd for Vec<'a, T, A> {
362 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
363 (**self).partial_cmp(&**other)
364 }
365}
366
367impl<'a, T: Ord, A: Allocator> Ord for Vec<'a, T, A> {
368 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
369 (**self).cmp(&**other)
370 }
371}
372
373impl<'a, T, A: Allocator, I: std::slice::SliceIndex<[T]>> std::ops::Index<I> for Vec<'a, T, A> {
374 type Output = I::Output;
375 #[inline]
376 fn index(&self, index: I) -> &Self::Output {
377 std::ops::Index::index(&**self, index)
378 }
379}
380
381impl<'a, T, A: Allocator, I: std::slice::SliceIndex<[T]>> std::ops::IndexMut<I> for Vec<'a, T, A> {
382 #[inline]
383 fn index_mut(&mut self, index: I) -> &mut Self::Output {
384 std::ops::IndexMut::index_mut(&mut **self, index)
385 }
386}
387
388impl<'a, T: Hash, A: Allocator> Hash for Vec<'a, T, A> {
389 fn hash<H: Hasher>(&self, state: &mut H) {
390 (**self).hash(state);
391 }
392}
393
394impl<'a, T, A: Allocator> AsRef<[T]> for Vec<'a, T, A> {
395 #[inline]
396 fn as_ref(&self) -> &[T] {
397 self
398 }
399}
400
401impl<'v, 'a, T, A: Allocator> IntoIterator for &'v Vec<'a, T, A> {
402 type Item = &'v T;
403 type IntoIter = std::slice::Iter<'v, T>;
404 #[inline]
405 fn into_iter(self) -> Self::IntoIter {
406 self.iter()
407 }
408}
409
410impl<'v, 'a, T, A: Allocator> IntoIterator for &'v mut Vec<'a, T, A> {
411 type Item = &'v mut T;
412 type IntoIter = std::slice::IterMut<'v, T>;
413 #[inline]
414 fn into_iter(self) -> Self::IntoIter {
415 self.iter_mut()
416 }
417}
418
419impl<'a, T: 'a, A: Allocator> IntoIterator for Vec<'a, T, A> {
420 type Item = T;
421 type IntoIter = IntoIter<'a, T>;
422 #[inline]
423 fn into_iter(self) -> Self::IntoIter {
424 let iter =
425 IntoIter { ptr: self.raw.ptr.as_ptr(), index: 0, len: self.raw.len, marker: std::marker::PhantomData };
426 std::mem::forget(self);
427 iter
428 }
429}
430
431pub struct IntoIter<'a, T: 'a> {
433 ptr: *mut T,
434 index: u32,
435 len: u32,
436 marker: std::marker::PhantomData<&'a mut T>,
437}
438
439impl<'a, T> Iterator for IntoIter<'a, T> {
440 type Item = T;
441 #[inline]
442 fn next(&mut self) -> Option<T> {
443 if self.index == self.len {
444 return None;
445 }
446 let value = unsafe { self.ptr.add(self.index as usize).read() };
447 self.index += 1;
448 Some(value)
449 }
450
451 #[inline]
452 fn size_hint(&self) -> (usize, Option<usize>) {
453 let remaining = (self.len - self.index) as usize;
454 (remaining, Some(remaining))
455 }
456}
457
458impl<'a, T> Drop for IntoIter<'a, T> {
459 fn drop(&mut self) {
460 while self.next().is_some() {}
461 }
462}
463
464pub struct Drain<'v, T> {
466 ptr: *mut T,
468 index: u32,
470 end: u32,
472 tail: u32,
474 vec_len: NonNull<u32>,
476 marker: std::marker::PhantomData<&'v mut T>,
477}
478
479impl<'v, T> Iterator for Drain<'v, T> {
480 type Item = T;
481 #[inline]
482 fn next(&mut self) -> Option<T> {
483 if self.index == self.end {
484 return None;
485 }
486 let value = unsafe { self.ptr.add(self.index as usize).read() };
487 self.index += 1;
488 Some(value)
489 }
490}
491
492impl<'v, T> Drop for Drain<'v, T> {
493 fn drop(&mut self) {
494 while self.index < self.end {
495 unsafe { self.ptr.add(self.index as usize).drop_in_place() };
496 self.index += 1;
497 }
498 let drained = self.end;
499 let tail = self.tail;
500 debug_assert!(drained <= tail, "drain end must not exceed the original length");
501 let count = tail - drained;
502 unsafe {
503 let start = *self.vec_len.as_ptr();
504 debug_assert!(start <= drained, "drain start must not exceed the drained region start");
505 if count > 0 {
506 std::ptr::copy(self.ptr.add(drained as usize), self.ptr.add(start as usize), count as usize);
507 }
508 *self.vec_len.as_ptr() = start + count;
509 }
510 }
511}
512
513#[cfg(feature = "serde")]
514impl<'a, T: serde::Serialize, A: Allocator> serde::Serialize for Vec<'a, T, A> {
515 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
516 serializer.collect_seq(self.iter())
517 }
518}
519
520#[cfg(test)]
521mod test {
522 use super::Vec;
523 use crate::Arena;
524 use std::cell::Cell;
525 use std::panic::{AssertUnwindSafe, catch_unwind};
526 use std::rc::Rc;
527
528 #[derive(Clone)]
529 struct DropCounter {
530 id: u32,
531 drops: Rc<Cell<u32>>,
532 }
533
534 impl DropCounter {
535 fn new(id: u32, drops: &Rc<Cell<u32>>) -> Self {
536 Self { id, drops: Rc::clone(drops) }
537 }
538 }
539
540 impl Drop for DropCounter {
541 fn drop(&mut self) {
542 self.drops.set(self.drops.get() + 1);
543 }
544 }
545
546 #[test]
547 fn new_is_empty_and_allocates_nothing() {
548 let alloc = Arena::new();
549 let v: Vec<i32> = Vec::new_in(&alloc);
550 assert!(v.is_empty());
551 assert_eq!(v.len(), 0);
552 assert_eq!(v.capacity(), 0);
553 assert_eq!(v.as_slice(), &[] as &[i32]);
554 }
555
556 #[test]
557 fn with_capacity_reserves_but_stays_empty() {
558 let alloc = Arena::new();
559 let v: Vec<i32> = Vec::with_capacity_in(16, &alloc);
560 assert!(v.is_empty());
561 assert_eq!(v.len(), 0);
562 assert!(v.capacity() >= 16);
563 }
564
565 #[test]
566 fn with_capacity_zero_allocates_nothing() {
567 let alloc = Arena::new();
568 let v: Vec<i32> = Vec::with_capacity_in(0, &alloc);
569 assert_eq!(v.capacity(), 0);
570 }
571
572 #[test]
573 fn push_grows_and_preserves_order() {
574 let alloc = Arena::new();
575 let mut v: Vec<u32> = Vec::new_in(&alloc);
576 for i in 0..1000u32 {
577 v.push(i);
578 }
579 assert_eq!(v.len(), 1000);
580 assert!(v.capacity() >= 1000);
581 for (i, &value) in v.iter().enumerate() {
582 assert_eq!(value, i as u32, "element is still in vec");
583 }
584 }
585
586 #[test]
587 fn pop_returns_last_then_none() {
588 let alloc = Arena::new();
589 let mut v: Vec<i32> = Vec::new_in(&alloc);
590 v.extend([10, 20, 30]);
591 assert_eq!(v.pop(), Some(30));
592 assert_eq!(v.pop(), Some(20));
593 assert_eq!(v.pop(), Some(10));
594 assert_eq!(v.pop(), None);
595 assert!(v.is_empty());
596 }
597
598 #[test]
599 fn insert_at_boundaries_and_middle() {
600 let alloc = Arena::new();
601 let mut v: Vec<i32> = Vec::new_in(&alloc);
602 v.extend([1, 2, 3]);
603 v.insert(0, 0); assert_eq!(&*v, &[0, 1, 2, 3]);
605 v.insert(v.len(), 4); assert_eq!(&*v, &[0, 1, 2, 3, 4]);
607 v.insert(2, 99); assert_eq!(&*v, &[0, 1, 99, 2, 3, 4]);
609 }
610
611 #[test]
612 fn insert_into_empty() {
613 let alloc = Arena::new();
614 let mut v: Vec<i32> = Vec::new_in(&alloc);
615 v.insert(0, 42);
616 assert_eq!(&*v, &[42]);
617 }
618
619 #[test]
620 fn insert_out_of_bounds_panics() {
621 let alloc = Arena::new();
622 let mut v: Vec<i32> = Vec::new_in(&alloc);
623 v.extend([1, 2]);
624 let result = catch_unwind(AssertUnwindSafe(|| v.insert(3, 0)));
625 assert!(result.is_err());
626 }
627
628 #[test]
629 fn remove_at_boundaries_and_middle() {
630 let alloc = Arena::new();
631 let mut v: Vec<i32> = Vec::new_in(&alloc);
632 v.extend([0, 1, 2, 3, 4]);
633 assert_eq!(v.remove(0), 0); assert_eq!(&*v, &[1, 2, 3, 4]);
635 assert_eq!(v.remove(v.len() - 1), 4); assert_eq!(&*v, &[1, 2, 3]);
637 assert_eq!(v.remove(1), 2); assert_eq!(&*v, &[1, 3]);
639 }
640
641 #[test]
642 fn remove_out_of_bounds_panics() {
643 let alloc = Arena::new();
644 let mut v: Vec<i32> = Vec::new_in(&alloc);
645 v.extend([1, 2]);
646 let result = catch_unwind(AssertUnwindSafe(|| v.remove(2)));
647 assert!(result.is_err());
648 }
649
650 #[test]
651 fn truncate_shortens_without_dropping() {
652 let alloc = Arena::new();
653 let drops = Rc::new(Cell::new(0));
654 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
655 for i in 0..5 {
656 v.push(DropCounter::new(i, &drops));
657 }
658 v.truncate(2);
659 assert_eq!(v.len(), 2);
660 assert_eq!(drops.get(), 0, "truncate must not run destructors");
661 }
662
663 #[test]
664 fn truncate_longer_than_len_is_noop() {
665 let alloc = Arena::new();
666 let mut v: Vec<i32> = Vec::new_in(&alloc);
667 v.extend([1, 2, 3]);
668 v.truncate(10);
669 assert_eq!(&*v, &[1, 2, 3]);
670 }
671
672 #[test]
673 fn clear_empties_without_dropping() {
674 let alloc = Arena::new();
675 let drops = Rc::new(Cell::new(0));
676 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
677 for i in 0..3 {
678 v.push(DropCounter::new(i, &drops));
679 }
680 v.clear();
681 assert!(v.is_empty());
682 assert_eq!(drops.get(), 0, "clear must not run destructors");
683 }
684
685 #[test]
686 fn extend_from_slice_clones_elements() {
687 let alloc = Arena::new();
688 let mut v: Vec<i32> = Vec::new_in(&alloc);
689 v.push(1);
690 v.extend_from_slice(&[2, 3, 4]);
691 assert_eq!(&*v, &[1, 2, 3, 4]);
692 }
693
694 #[test]
695 fn extend_with_accurate_size_hint_reserves_once() {
696 let alloc = Arena::new();
697 let mut v: Vec<u32> = Vec::new_in(&alloc);
698 v.extend(0..64u32);
699 assert_eq!(v.len(), 64);
700 for i in 0..64u32 {
701 assert_eq!(v[i as usize], i);
702 }
703 }
704
705 #[test]
706 fn extend_empty_iterator_is_noop() {
707 let alloc = Arena::new();
708 let mut v: Vec<u32> = Vec::new_in(&alloc);
709 v.extend(std::iter::empty::<u32>());
710 assert!(v.is_empty());
711 assert_eq!(v.capacity(), 0);
712 }
713
714 #[test]
715 fn retain_keeps_matching_and_shifts() {
716 let alloc = Arena::new();
717 let mut v: Vec<i32> = Vec::new_in(&alloc);
718 v.extend([0, 1, 2, 3, 4, 5, 6, 7]);
719 v.retain(|&x| x % 2 == 0);
720 assert_eq!(&*v, &[0, 2, 4, 6]);
721 }
722
723 #[test]
724 fn dedup_collapses_consecutive_runs_only() {
725 let alloc = Arena::new();
726 let mut v: Vec<i32> = Vec::new_in(&alloc);
727 v.extend([1, 1, 2, 3, 3, 3, 1, 1]);
728 v.dedup();
729 assert_eq!(&*v, &[1, 2, 3, 1]);
730 }
731
732 #[test]
733 fn dedup_leaves_short_and_distinct_vectors_alone() {
734 let alloc = Arena::new();
735 let mut v: Vec<i32> = Vec::new_in(&alloc);
736 v.dedup();
737 assert!(v.is_empty());
738 v.extend([1, 2, 3]);
739 v.dedup();
740 assert_eq!(&*v, &[1, 2, 3]);
741 let mut same: Vec<i32> = Vec::new_in(&alloc);
742 same.extend([7, 7, 7]);
743 same.dedup();
744 assert_eq!(&*same, &[7]);
745 }
746
747 #[test]
748 fn retain_all_and_none() {
749 let alloc = Arena::new();
750 let mut v: Vec<i32> = Vec::new_in(&alloc);
751 v.extend([1, 2, 3]);
752 v.retain(|_| true);
753 assert_eq!(&*v, &[1, 2, 3]);
754 v.retain(|_| false);
755 assert!(v.is_empty());
756 }
757
758 #[test]
759 fn retain_drops_removed_exactly_once() {
760 let alloc = Arena::new();
761 let drops = Rc::new(Cell::new(0));
762 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
763 for i in 0..6 {
764 v.push(DropCounter::new(i, &drops));
765 }
766 v.retain(|c| c.id % 2 == 1);
767 assert_eq!(v.len(), 3);
768 assert_eq!(drops.get(), 3, "each removed element dropped exactly once");
769 let ids: std::vec::Vec<u32> = v.iter().map(|c| c.id).collect();
770 assert_eq!(ids, vec![1, 3, 5], "survivors intact and in order after write-back");
771 }
772
773 #[test]
774 fn retain_panic_drops_no_element_twice() {
775 let alloc = Arena::new();
776 let drops = Rc::new(Cell::new(0));
777 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
778 for i in 0..5 {
779 v.push(DropCounter::new(i, &drops));
780 }
781 let drops_for_closure = Rc::clone(&drops);
782 let result = catch_unwind(AssertUnwindSafe(|| {
783 v.retain(|c| {
784 if c.id == 3 {
785 panic!("boom");
786 }
787 c.id >= 2
789 });
790 }));
791 assert!(result.is_err());
792 let removed = drops_for_closure.get();
793 assert_eq!(removed, 2, "only the elements filtered out before the panic were dropped");
794 assert_eq!(v.len() as u32 + removed, 5, "no leaked or double-counted elements");
795 }
796
797 #[test]
798 fn drain_empty_range() {
799 let alloc = Arena::new();
800 let mut v: Vec<i32> = Vec::new_in(&alloc);
801 v.extend([1, 2, 3]);
802 let drained: std::vec::Vec<i32> = v.drain(1..1).collect();
803 assert!(drained.is_empty());
804 assert_eq!(&*v, &[1, 2, 3]);
805 }
806
807 #[test]
808 fn drain_suffix() {
809 let alloc = Arena::new();
810 let mut v: Vec<i32> = Vec::new_in(&alloc);
811 v.extend([0, 1, 2, 3, 4]);
812 let drained: std::vec::Vec<i32> = v.drain(3..).collect();
813 assert_eq!(drained, vec![3, 4]);
814 assert_eq!(&*v, &[0, 1, 2]);
815 }
816
817 #[test]
818 fn drain_inclusive_bound() {
819 let alloc = Arena::new();
820 let mut v: Vec<i32> = Vec::new_in(&alloc);
821 v.extend([0, 1, 2, 3, 4]);
822 let drained: std::vec::Vec<i32> = v.drain(1..=3).collect();
823 assert_eq!(drained, vec![1, 2, 3]);
824 assert_eq!(&*v, &[0, 4]);
825 }
826
827 #[test]
828 fn drain_start_after_end_panics() {
829 let alloc = Arena::new();
830 let mut v: Vec<i32> = Vec::new_in(&alloc);
831 v.extend([0, 1, 2]);
832 use std::ops::Bound;
833 let bad_range = (Bound::Included(2u32), Bound::Excluded(1u32));
834 let result = catch_unwind(AssertUnwindSafe(|| {
835 let _ = v.drain(bad_range);
836 }));
837 assert!(result.is_err());
838 }
839
840 #[test]
841 fn drain_out_of_bounds_panics() {
842 let alloc = Arena::new();
843 let mut v: Vec<i32> = Vec::new_in(&alloc);
844 v.extend([0, 1, 2]);
845 let result = catch_unwind(AssertUnwindSafe(|| {
846 let _ = v.drain(1..99);
847 }));
848 assert!(result.is_err());
849 }
850
851 #[test]
852 fn drain_yielded_and_remaining_drop_exactly_once() {
853 let alloc = Arena::new();
854 let drops = Rc::new(Cell::new(0));
855 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
856 for i in 0..6 {
857 v.push(DropCounter::new(i, &drops));
858 }
859 {
860 let mut d = v.drain(1..4);
861 let first = d.next().unwrap();
862 assert_eq!(first.id, 1);
863 drop(first); }
866 assert_eq!(drops.get(), 3, "drained range dropped exactly once total");
867 let ids: std::vec::Vec<u32> = v.iter().map(|c| c.id).collect();
868 assert_eq!(ids, vec![0, 4, 5], "tail shifted correctly after partial drain");
869 }
870
871 #[test]
872 fn drain_fully_consumed_then_no_extra_drops() {
873 let alloc = Arena::new();
874 let drops = Rc::new(Cell::new(0));
875 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
876 for i in 0..4 {
877 v.push(DropCounter::new(i, &drops));
878 }
879 let collected: std::vec::Vec<DropCounter> = v.drain(..).collect();
880 let ids: std::vec::Vec<u32> = collected.iter().map(|c| c.id).collect();
881 assert_eq!(ids, vec![0, 1, 2, 3]);
882 assert_eq!(drops.get(), 0);
884 assert!(v.is_empty());
885 drop(collected);
886 assert_eq!(drops.get(), 4, "each drained element dropped exactly once when the collection drops");
887 }
888
889 #[test]
890 fn drain_size_hint_not_relied_on_but_iteration_correct() {
891 let alloc = Arena::new();
892 let mut v: Vec<i32> = Vec::new_in(&alloc);
893 v.extend([5, 6, 7, 8]);
894 let mut iter = v.drain(0..4);
895 assert_eq!(iter.next(), Some(5));
896 assert_eq!(iter.next(), Some(6));
897 assert_eq!(iter.next(), Some(7));
898 assert_eq!(iter.next(), Some(8));
899 assert_eq!(iter.next(), None);
900 }
901
902 #[test]
903 fn drain_prefix_shifts_tail() {
904 let alloc = Arena::default();
905 let mut v: Vec<i32> = Vec::new_in(&alloc);
906 v.extend([0, 1, 2, 3, 4, 5]);
907 let drained: std::vec::Vec<i32> = v.drain(0..2).collect();
908 assert_eq!(drained, vec![0, 1]);
909 assert_eq!(&*v, &[2, 3, 4, 5]);
910 }
911
912 #[test]
913 fn drain_middle_shifts_tail() {
914 let alloc = Arena::default();
915 let mut v: Vec<i32> = Vec::new_in(&alloc);
916 v.extend([0, 1, 2, 3, 4, 5]);
917 let drained: std::vec::Vec<i32> = v.drain(2..4).collect();
918 assert_eq!(drained, vec![2, 3]);
919 assert_eq!(&*v, &[0, 1, 4, 5]);
920 }
921
922 #[test]
923 fn drain_full_range() {
924 let alloc = Arena::default();
925 let mut v: Vec<i32> = Vec::new_in(&alloc);
926 v.extend([1, 2, 3]);
927 let drained: std::vec::Vec<i32> = v.drain(..).collect();
928 assert_eq!(drained, vec![1, 2, 3]);
929 assert!(v.is_empty());
930 }
931
932 #[test]
933 fn drain_dropped_without_iterating_still_shifts() {
934 let alloc = Arena::default();
935 let mut v: Vec<i32> = Vec::new_in(&alloc);
936 v.extend([0, 1, 2, 3, 4]);
937 drop(v.drain(1..3));
938 assert_eq!(&*v, &[0, 3, 4]);
939 }
940
941 #[test]
942 fn retain_preserves_length_when_predicate_panics() {
943 let alloc = Arena::new();
944 let mut values = Vec::new_in(&alloc);
945 values.extend([0, 1, 2]);
946 let calls = Cell::new(0);
947
948 let result = catch_unwind(AssertUnwindSafe(|| {
949 values.retain(|_| {
950 let call = calls.get();
951 calls.set(call + 1);
952 match call {
953 0 => false,
954 1 => true,
955 _ => panic!("predicate failed"),
956 }
957 });
958 }));
959
960 assert!(result.is_err());
961 assert_eq!(values.len(), 2, "moved-from slots must not remain visible");
962 }
963
964 #[test]
965 fn into_iter_yields_all_in_order() {
966 let alloc = Arena::new();
967 let mut v: Vec<i32> = Vec::new_in(&alloc);
968 v.extend([1, 2, 3, 4]);
969 let collected: std::vec::Vec<i32> = v.into_iter().collect();
970 assert_eq!(collected, vec![1, 2, 3, 4]);
971 }
972
973 #[test]
974 fn into_iter_size_hint_is_exact() {
975 let alloc = Arena::new();
976 let mut v: Vec<i32> = Vec::new_in(&alloc);
977 v.extend([1, 2, 3]);
978 let mut iter = v.into_iter();
979 assert_eq!(iter.size_hint(), (3, Some(3)));
980 iter.next();
981 assert_eq!(iter.size_hint(), (2, Some(2)));
982 }
983
984 #[test]
985 fn into_iter_partial_consume_drops_remainder_once() {
986 let alloc = Arena::new();
987 let drops = Rc::new(Cell::new(0));
988 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
989 for i in 0..5 {
990 v.push(DropCounter::new(i, &drops));
991 }
992 {
993 let mut iter = v.into_iter();
994 let a = iter.next().unwrap();
995 let b = iter.next().unwrap();
996 assert_eq!((a.id, b.id), (0, 1));
997 drop(a); drop(b); }
1001 assert_eq!(drops.get(), 5, "every element dropped exactly once across manual + IntoIter drop");
1002 }
1003
1004 #[test]
1005 fn into_iter_fully_consumed_no_leak() {
1006 let alloc = Arena::new();
1007 let drops = Rc::new(Cell::new(0));
1008 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
1009 for i in 0..4 {
1010 v.push(DropCounter::new(i, &drops));
1011 }
1012 for c in v {
1013 let _ = c.id; }
1015 assert_eq!(drops.get(), 4);
1016 }
1017
1018 #[test]
1019 fn clone_is_independent_copy() {
1020 let alloc = Arena::new();
1021 let mut v: Vec<i32> = Vec::new_in(&alloc);
1022 v.extend([1, 2, 3]);
1023 let mut c = v.clone();
1024 c.push(4);
1025 assert_eq!(&*v, &[1, 2, 3], "original unchanged after mutating clone");
1026 assert_eq!(&*c, &[1, 2, 3, 4]);
1027 }
1028
1029 #[test]
1030 fn eq_and_ord_delegate_to_slice() {
1031 let alloc = Arena::new();
1032 let mut a: Vec<i32> = Vec::new_in(&alloc);
1033 a.extend([1, 2, 3]);
1034 let mut b: Vec<i32> = Vec::new_in(&alloc);
1035 b.extend([1, 2, 3]);
1036 assert_eq!(a, b);
1037 let mut c: Vec<i32> = Vec::new_in(&alloc);
1038 c.extend([1, 2, 4]);
1039 assert!(a < c);
1040 assert_ne!(a, c);
1041 }
1042
1043 #[test]
1044 fn index_and_index_mut() {
1045 let alloc = Arena::new();
1046 let mut v: Vec<i32> = Vec::new_in(&alloc);
1047 v.extend([10, 20, 30]);
1048 assert_eq!(v[1], 20);
1049 v[1] = 99;
1050 assert_eq!(v[1], 99);
1051 assert_eq!(&v[0..2], &[10, 99]);
1052 }
1053
1054 #[test]
1055 fn hash_matches_equal_vecs() {
1056 use std::collections::hash_map::DefaultHasher;
1057 use std::hash::{Hash, Hasher};
1058 let alloc = Arena::new();
1059 let mut a: Vec<i32> = Vec::new_in(&alloc);
1060 a.extend([1, 2, 3]);
1061 let mut b: Vec<i32> = Vec::new_in(&alloc);
1062 b.extend([1, 2, 3]);
1063 let mut ha = DefaultHasher::new();
1064 let mut hb = DefaultHasher::new();
1065 a.hash(&mut ha);
1066 b.hash(&mut hb);
1067 assert_eq!(ha.finish(), hb.finish());
1068 }
1069
1070 #[test]
1071 fn realloc_preserves_boxed_contents() {
1072 let alloc = Arena::new();
1073 let mut v: Vec<std::boxed::Box<u32>> = Vec::new_in(&alloc);
1074 for i in 0..512u32 {
1075 v.push(std::boxed::Box::new(i));
1076 }
1077 for (i, b) in v.iter().enumerate() {
1078 assert_eq!(**b, i as u32);
1079 }
1080 let sum: u32 = v.into_iter().map(|b| *b).sum();
1081 assert_eq!(sum, (0..512u32).sum());
1082 }
1083
1084 #[test]
1085 fn zero_sized_type_push_pop_len() {
1086 let alloc = Arena::new();
1087 let mut v: Vec<()> = Vec::new_in(&alloc);
1088 for _ in 0..100 {
1089 v.push(());
1090 }
1091 assert_eq!(v.len(), 100);
1092 for _ in 0..100 {
1093 assert_eq!(v.pop(), Some(()));
1094 }
1095 assert_eq!(v.pop(), None);
1096 }
1097}