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 use super::Vec;
510 use crate::Arena;
511 use std::cell::Cell;
512 use std::panic::{AssertUnwindSafe, catch_unwind};
513 use std::rc::Rc;
514
515 #[derive(Clone)]
516 struct DropCounter {
517 id: u32,
518 drops: Rc<Cell<u32>>,
519 }
520
521 impl DropCounter {
522 fn new(id: u32, drops: &Rc<Cell<u32>>) -> Self {
523 Self { id, drops: Rc::clone(drops) }
524 }
525 }
526
527 impl Drop for DropCounter {
528 fn drop(&mut self) {
529 self.drops.set(self.drops.get() + 1);
530 }
531 }
532
533 #[test]
534 fn new_is_empty_and_allocates_nothing() {
535 let alloc = Arena::new();
536 let v: Vec<i32> = Vec::new_in(&alloc);
537 assert!(v.is_empty());
538 assert_eq!(v.len(), 0);
539 assert_eq!(v.capacity(), 0);
540 assert_eq!(v.as_slice(), &[] as &[i32]);
541 }
542
543 #[test]
544 fn with_capacity_reserves_but_stays_empty() {
545 let alloc = Arena::new();
546 let v: Vec<i32> = Vec::with_capacity_in(16, &alloc);
547 assert!(v.is_empty());
548 assert_eq!(v.len(), 0);
549 assert!(v.capacity() >= 16);
550 }
551
552 #[test]
553 fn with_capacity_zero_allocates_nothing() {
554 let alloc = Arena::new();
555 let v: Vec<i32> = Vec::with_capacity_in(0, &alloc);
556 assert_eq!(v.capacity(), 0);
557 }
558
559 #[test]
560 fn push_grows_and_preserves_order() {
561 let alloc = Arena::new();
562 let mut v: Vec<u32> = Vec::new_in(&alloc);
563 for i in 0..1000u32 {
564 v.push(i);
565 }
566 assert_eq!(v.len(), 1000);
567 assert!(v.capacity() >= 1000);
568 for (i, &value) in v.iter().enumerate() {
569 assert_eq!(value, i as u32, "element is still in vec");
570 }
571 }
572
573 #[test]
574 fn pop_returns_last_then_none() {
575 let alloc = Arena::new();
576 let mut v: Vec<i32> = Vec::new_in(&alloc);
577 v.extend([10, 20, 30]);
578 assert_eq!(v.pop(), Some(30));
579 assert_eq!(v.pop(), Some(20));
580 assert_eq!(v.pop(), Some(10));
581 assert_eq!(v.pop(), None);
582 assert!(v.is_empty());
583 }
584
585 #[test]
586 fn insert_at_boundaries_and_middle() {
587 let alloc = Arena::new();
588 let mut v: Vec<i32> = Vec::new_in(&alloc);
589 v.extend([1, 2, 3]);
590 v.insert(0, 0); assert_eq!(&*v, &[0, 1, 2, 3]);
592 v.insert(v.len(), 4); assert_eq!(&*v, &[0, 1, 2, 3, 4]);
594 v.insert(2, 99); assert_eq!(&*v, &[0, 1, 99, 2, 3, 4]);
596 }
597
598 #[test]
599 fn insert_into_empty() {
600 let alloc = Arena::new();
601 let mut v: Vec<i32> = Vec::new_in(&alloc);
602 v.insert(0, 42);
603 assert_eq!(&*v, &[42]);
604 }
605
606 #[test]
607 fn insert_out_of_bounds_panics() {
608 let alloc = Arena::new();
609 let mut v: Vec<i32> = Vec::new_in(&alloc);
610 v.extend([1, 2]);
611 let result = catch_unwind(AssertUnwindSafe(|| v.insert(3, 0)));
612 assert!(result.is_err());
613 }
614
615 #[test]
616 fn remove_at_boundaries_and_middle() {
617 let alloc = Arena::new();
618 let mut v: Vec<i32> = Vec::new_in(&alloc);
619 v.extend([0, 1, 2, 3, 4]);
620 assert_eq!(v.remove(0), 0); assert_eq!(&*v, &[1, 2, 3, 4]);
622 assert_eq!(v.remove(v.len() - 1), 4); assert_eq!(&*v, &[1, 2, 3]);
624 assert_eq!(v.remove(1), 2); assert_eq!(&*v, &[1, 3]);
626 }
627
628 #[test]
629 fn remove_out_of_bounds_panics() {
630 let alloc = Arena::new();
631 let mut v: Vec<i32> = Vec::new_in(&alloc);
632 v.extend([1, 2]);
633 let result = catch_unwind(AssertUnwindSafe(|| v.remove(2)));
634 assert!(result.is_err());
635 }
636
637 #[test]
638 fn truncate_shortens_without_dropping() {
639 let alloc = Arena::new();
640 let drops = Rc::new(Cell::new(0));
641 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
642 for i in 0..5 {
643 v.push(DropCounter::new(i, &drops));
644 }
645 v.truncate(2);
646 assert_eq!(v.len(), 2);
647 assert_eq!(drops.get(), 0, "truncate must not run destructors");
648 }
649
650 #[test]
651 fn truncate_longer_than_len_is_noop() {
652 let alloc = Arena::new();
653 let mut v: Vec<i32> = Vec::new_in(&alloc);
654 v.extend([1, 2, 3]);
655 v.truncate(10);
656 assert_eq!(&*v, &[1, 2, 3]);
657 }
658
659 #[test]
660 fn clear_empties_without_dropping() {
661 let alloc = Arena::new();
662 let drops = Rc::new(Cell::new(0));
663 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
664 for i in 0..3 {
665 v.push(DropCounter::new(i, &drops));
666 }
667 v.clear();
668 assert!(v.is_empty());
669 assert_eq!(drops.get(), 0, "clear must not run destructors");
670 }
671
672 #[test]
673 fn extend_from_slice_clones_elements() {
674 let alloc = Arena::new();
675 let mut v: Vec<i32> = Vec::new_in(&alloc);
676 v.push(1);
677 v.extend_from_slice(&[2, 3, 4]);
678 assert_eq!(&*v, &[1, 2, 3, 4]);
679 }
680
681 #[test]
682 fn extend_with_accurate_size_hint_reserves_once() {
683 let alloc = Arena::new();
684 let mut v: Vec<u32> = Vec::new_in(&alloc);
685 v.extend(0..64u32);
686 assert_eq!(v.len(), 64);
687 for i in 0..64u32 {
688 assert_eq!(v[i as usize], i);
689 }
690 }
691
692 #[test]
693 fn extend_empty_iterator_is_noop() {
694 let alloc = Arena::new();
695 let mut v: Vec<u32> = Vec::new_in(&alloc);
696 v.extend(std::iter::empty::<u32>());
697 assert!(v.is_empty());
698 assert_eq!(v.capacity(), 0);
699 }
700
701 #[test]
702 fn retain_keeps_matching_and_shifts() {
703 let alloc = Arena::new();
704 let mut v: Vec<i32> = Vec::new_in(&alloc);
705 v.extend([0, 1, 2, 3, 4, 5, 6, 7]);
706 v.retain(|&x| x % 2 == 0);
707 assert_eq!(&*v, &[0, 2, 4, 6]);
708 }
709
710 #[test]
711 fn retain_all_and_none() {
712 let alloc = Arena::new();
713 let mut v: Vec<i32> = Vec::new_in(&alloc);
714 v.extend([1, 2, 3]);
715 v.retain(|_| true);
716 assert_eq!(&*v, &[1, 2, 3]);
717 v.retain(|_| false);
718 assert!(v.is_empty());
719 }
720
721 #[test]
722 fn retain_drops_removed_exactly_once() {
723 let alloc = Arena::new();
724 let drops = Rc::new(Cell::new(0));
725 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
726 for i in 0..6 {
727 v.push(DropCounter::new(i, &drops));
728 }
729 v.retain(|c| c.id % 2 == 1);
730 assert_eq!(v.len(), 3);
731 assert_eq!(drops.get(), 3, "each removed element dropped exactly once");
732 let ids: std::vec::Vec<u32> = v.iter().map(|c| c.id).collect();
733 assert_eq!(ids, vec![1, 3, 5], "survivors intact and in order after write-back");
734 }
735
736 #[test]
737 fn retain_panic_drops_no_element_twice() {
738 let alloc = Arena::new();
739 let drops = Rc::new(Cell::new(0));
740 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
741 for i in 0..5 {
742 v.push(DropCounter::new(i, &drops));
743 }
744 let drops_for_closure = Rc::clone(&drops);
745 let result = catch_unwind(AssertUnwindSafe(|| {
746 v.retain(|c| {
747 if c.id == 3 {
748 panic!("boom");
749 }
750 c.id >= 2
752 });
753 }));
754 assert!(result.is_err());
755 let removed = drops_for_closure.get();
756 assert_eq!(removed, 2, "only the elements filtered out before the panic were dropped");
757 assert_eq!(v.len() as u32 + removed, 5, "no leaked or double-counted elements");
758 }
759
760 #[test]
761 fn drain_empty_range() {
762 let alloc = Arena::new();
763 let mut v: Vec<i32> = Vec::new_in(&alloc);
764 v.extend([1, 2, 3]);
765 let drained: std::vec::Vec<i32> = v.drain(1..1).collect();
766 assert!(drained.is_empty());
767 assert_eq!(&*v, &[1, 2, 3]);
768 }
769
770 #[test]
771 fn drain_suffix() {
772 let alloc = Arena::new();
773 let mut v: Vec<i32> = Vec::new_in(&alloc);
774 v.extend([0, 1, 2, 3, 4]);
775 let drained: std::vec::Vec<i32> = v.drain(3..).collect();
776 assert_eq!(drained, vec![3, 4]);
777 assert_eq!(&*v, &[0, 1, 2]);
778 }
779
780 #[test]
781 fn drain_inclusive_bound() {
782 let alloc = Arena::new();
783 let mut v: Vec<i32> = Vec::new_in(&alloc);
784 v.extend([0, 1, 2, 3, 4]);
785 let drained: std::vec::Vec<i32> = v.drain(1..=3).collect();
786 assert_eq!(drained, vec![1, 2, 3]);
787 assert_eq!(&*v, &[0, 4]);
788 }
789
790 #[test]
791 fn drain_start_after_end_panics() {
792 let alloc = Arena::new();
793 let mut v: Vec<i32> = Vec::new_in(&alloc);
794 v.extend([0, 1, 2]);
795 use std::ops::Bound;
796 let bad_range = (Bound::Included(2u32), Bound::Excluded(1u32));
797 let result = catch_unwind(AssertUnwindSafe(|| {
798 let _ = v.drain(bad_range);
799 }));
800 assert!(result.is_err());
801 }
802
803 #[test]
804 fn drain_out_of_bounds_panics() {
805 let alloc = Arena::new();
806 let mut v: Vec<i32> = Vec::new_in(&alloc);
807 v.extend([0, 1, 2]);
808 let result = catch_unwind(AssertUnwindSafe(|| {
809 let _ = v.drain(1..99);
810 }));
811 assert!(result.is_err());
812 }
813
814 #[test]
815 fn drain_yielded_and_remaining_drop_exactly_once() {
816 let alloc = Arena::new();
817 let drops = Rc::new(Cell::new(0));
818 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
819 for i in 0..6 {
820 v.push(DropCounter::new(i, &drops));
821 }
822 {
823 let mut d = v.drain(1..4);
824 let first = d.next().unwrap();
825 assert_eq!(first.id, 1);
826 drop(first); }
829 assert_eq!(drops.get(), 3, "drained range dropped exactly once total");
830 let ids: std::vec::Vec<u32> = v.iter().map(|c| c.id).collect();
831 assert_eq!(ids, vec![0, 4, 5], "tail shifted correctly after partial drain");
832 }
833
834 #[test]
835 fn drain_fully_consumed_then_no_extra_drops() {
836 let alloc = Arena::new();
837 let drops = Rc::new(Cell::new(0));
838 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
839 for i in 0..4 {
840 v.push(DropCounter::new(i, &drops));
841 }
842 let collected: std::vec::Vec<DropCounter> = v.drain(..).collect();
843 let ids: std::vec::Vec<u32> = collected.iter().map(|c| c.id).collect();
844 assert_eq!(ids, vec![0, 1, 2, 3]);
845 assert_eq!(drops.get(), 0);
847 assert!(v.is_empty());
848 drop(collected);
849 assert_eq!(drops.get(), 4, "each drained element dropped exactly once when the collection drops");
850 }
851
852 #[test]
853 fn drain_size_hint_not_relied_on_but_iteration_correct() {
854 let alloc = Arena::new();
855 let mut v: Vec<i32> = Vec::new_in(&alloc);
856 v.extend([5, 6, 7, 8]);
857 let mut iter = v.drain(0..4);
858 assert_eq!(iter.next(), Some(5));
859 assert_eq!(iter.next(), Some(6));
860 assert_eq!(iter.next(), Some(7));
861 assert_eq!(iter.next(), Some(8));
862 assert_eq!(iter.next(), None);
863 }
864
865 #[test]
866 fn drain_prefix_shifts_tail() {
867 let alloc = Arena::default();
868 let mut v: Vec<i32> = Vec::new_in(&alloc);
869 v.extend([0, 1, 2, 3, 4, 5]);
870 let drained: std::vec::Vec<i32> = v.drain(0..2).collect();
871 assert_eq!(drained, vec![0, 1]);
872 assert_eq!(&*v, &[2, 3, 4, 5]);
873 }
874
875 #[test]
876 fn drain_middle_shifts_tail() {
877 let alloc = Arena::default();
878 let mut v: Vec<i32> = Vec::new_in(&alloc);
879 v.extend([0, 1, 2, 3, 4, 5]);
880 let drained: std::vec::Vec<i32> = v.drain(2..4).collect();
881 assert_eq!(drained, vec![2, 3]);
882 assert_eq!(&*v, &[0, 1, 4, 5]);
883 }
884
885 #[test]
886 fn drain_full_range() {
887 let alloc = Arena::default();
888 let mut v: Vec<i32> = Vec::new_in(&alloc);
889 v.extend([1, 2, 3]);
890 let drained: std::vec::Vec<i32> = v.drain(..).collect();
891 assert_eq!(drained, vec![1, 2, 3]);
892 assert!(v.is_empty());
893 }
894
895 #[test]
896 fn drain_dropped_without_iterating_still_shifts() {
897 let alloc = Arena::default();
898 let mut v: Vec<i32> = Vec::new_in(&alloc);
899 v.extend([0, 1, 2, 3, 4]);
900 drop(v.drain(1..3));
901 assert_eq!(&*v, &[0, 3, 4]);
902 }
903
904 #[test]
905 fn retain_preserves_length_when_predicate_panics() {
906 let alloc = Arena::new();
907 let mut values = Vec::new_in(&alloc);
908 values.extend([0, 1, 2]);
909 let calls = Cell::new(0);
910
911 let result = catch_unwind(AssertUnwindSafe(|| {
912 values.retain(|_| {
913 let call = calls.get();
914 calls.set(call + 1);
915 match call {
916 0 => false,
917 1 => true,
918 _ => panic!("predicate failed"),
919 }
920 });
921 }));
922
923 assert!(result.is_err());
924 assert_eq!(values.len(), 2, "moved-from slots must not remain visible");
925 }
926
927 #[test]
928 fn into_iter_yields_all_in_order() {
929 let alloc = Arena::new();
930 let mut v: Vec<i32> = Vec::new_in(&alloc);
931 v.extend([1, 2, 3, 4]);
932 let collected: std::vec::Vec<i32> = v.into_iter().collect();
933 assert_eq!(collected, vec![1, 2, 3, 4]);
934 }
935
936 #[test]
937 fn into_iter_size_hint_is_exact() {
938 let alloc = Arena::new();
939 let mut v: Vec<i32> = Vec::new_in(&alloc);
940 v.extend([1, 2, 3]);
941 let mut iter = v.into_iter();
942 assert_eq!(iter.size_hint(), (3, Some(3)));
943 iter.next();
944 assert_eq!(iter.size_hint(), (2, Some(2)));
945 }
946
947 #[test]
948 fn into_iter_partial_consume_drops_remainder_once() {
949 let alloc = Arena::new();
950 let drops = Rc::new(Cell::new(0));
951 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
952 for i in 0..5 {
953 v.push(DropCounter::new(i, &drops));
954 }
955 {
956 let mut iter = v.into_iter();
957 let a = iter.next().unwrap();
958 let b = iter.next().unwrap();
959 assert_eq!((a.id, b.id), (0, 1));
960 drop(a); drop(b); }
964 assert_eq!(drops.get(), 5, "every element dropped exactly once across manual + IntoIter drop");
965 }
966
967 #[test]
968 fn into_iter_fully_consumed_no_leak() {
969 let alloc = Arena::new();
970 let drops = Rc::new(Cell::new(0));
971 let mut v: Vec<DropCounter> = Vec::new_in(&alloc);
972 for i in 0..4 {
973 v.push(DropCounter::new(i, &drops));
974 }
975 for c in v {
976 let _ = c.id; }
978 assert_eq!(drops.get(), 4);
979 }
980
981 #[test]
982 fn clone_is_independent_copy() {
983 let alloc = Arena::new();
984 let mut v: Vec<i32> = Vec::new_in(&alloc);
985 v.extend([1, 2, 3]);
986 let mut c = v.clone();
987 c.push(4);
988 assert_eq!(&*v, &[1, 2, 3], "original unchanged after mutating clone");
989 assert_eq!(&*c, &[1, 2, 3, 4]);
990 }
991
992 #[test]
993 fn eq_and_ord_delegate_to_slice() {
994 let alloc = Arena::new();
995 let mut a: Vec<i32> = Vec::new_in(&alloc);
996 a.extend([1, 2, 3]);
997 let mut b: Vec<i32> = Vec::new_in(&alloc);
998 b.extend([1, 2, 3]);
999 assert_eq!(a, b);
1000 let mut c: Vec<i32> = Vec::new_in(&alloc);
1001 c.extend([1, 2, 4]);
1002 assert!(a < c);
1003 assert_ne!(a, c);
1004 }
1005
1006 #[test]
1007 fn index_and_index_mut() {
1008 let alloc = Arena::new();
1009 let mut v: Vec<i32> = Vec::new_in(&alloc);
1010 v.extend([10, 20, 30]);
1011 assert_eq!(v[1], 20);
1012 v[1] = 99;
1013 assert_eq!(v[1], 99);
1014 assert_eq!(&v[0..2], &[10, 99]);
1015 }
1016
1017 #[test]
1018 fn hash_matches_equal_vecs() {
1019 use std::collections::hash_map::DefaultHasher;
1020 use std::hash::{Hash, Hasher};
1021 let alloc = Arena::new();
1022 let mut a: Vec<i32> = Vec::new_in(&alloc);
1023 a.extend([1, 2, 3]);
1024 let mut b: Vec<i32> = Vec::new_in(&alloc);
1025 b.extend([1, 2, 3]);
1026 let mut ha = DefaultHasher::new();
1027 let mut hb = DefaultHasher::new();
1028 a.hash(&mut ha);
1029 b.hash(&mut hb);
1030 assert_eq!(ha.finish(), hb.finish());
1031 }
1032
1033 #[test]
1034 fn realloc_preserves_boxed_contents() {
1035 let alloc = Arena::new();
1036 let mut v: Vec<std::boxed::Box<u32>> = Vec::new_in(&alloc);
1037 for i in 0..512u32 {
1038 v.push(std::boxed::Box::new(i));
1039 }
1040 for (i, b) in v.iter().enumerate() {
1041 assert_eq!(**b, i as u32);
1042 }
1043 let sum: u32 = v.into_iter().map(|b| *b).sum();
1044 assert_eq!(sum, (0..512u32).sum());
1045 }
1046
1047 #[test]
1048 fn zero_sized_type_push_pop_len() {
1049 let alloc = Arena::new();
1050 let mut v: Vec<()> = Vec::new_in(&alloc);
1051 for _ in 0..100 {
1052 v.push(());
1053 }
1054 assert_eq!(v.len(), 100);
1055 for _ in 0..100 {
1056 assert_eq!(v.pop(), Some(()));
1057 }
1058 assert_eq!(v.pop(), None);
1059 }
1060
1061 #[test]
1062 fn parsing_beyond_default_arena_capacity_does_not_panic() {
1063 use crate::{ComponentValues, EmptyAtomSet, Parser};
1064 use css_lexer::Lexer;
1065
1066 let source = "a ".repeat(16_384);
1067 let result = catch_unwind(AssertUnwindSafe(|| {
1068 let arena = Arena::new();
1069 let lexer = Lexer::new(&EmptyAtomSet::ATOMS, &source);
1070 let mut parser = Parser::new(&arena, &source, lexer);
1071 let _ = parser.parse_entirely::<ComponentValues>();
1072 }));
1073
1074 assert!(result.is_ok(), "arena exhaustion must not abort parsing");
1075 }
1076}