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