Skip to main content

alloc_checked/
vec.rs

1use crate::claim::Claim;
2use crate::try_clone::TryClone;
3use alloc::alloc::Allocator;
4use alloc::collections::TryReserveError;
5use alloc::vec::Vec as InnerVec;
6use core::fmt::Debug;
7use core::ops::{Deref, DerefMut, Index, IndexMut};
8use core::slice::SliceIndex;
9
10pub struct Vec<T, A: Allocator> {
11    inner: InnerVec<T, A>,
12}
13
14impl<T, A: Allocator> Vec<T, A> {
15    #[inline]
16    pub fn new_in(alloc: A) -> Self {
17        Self {
18            inner: InnerVec::new_in(alloc),
19        }
20    }
21
22    pub fn allocator(&self) -> &A {
23        self.inner.allocator()
24    }
25
26    #[inline]
27    pub fn capacity(&self) -> usize {
28        self.inner.capacity()
29    }
30
31    #[inline]
32    pub fn reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
33        self.inner.try_reserve(additional)
34    }
35
36    #[inline]
37    pub fn with_capacity_in(capacity: usize, alloc: A) -> Result<Self, TryReserveError> {
38        Ok(Self {
39            inner: InnerVec::try_with_capacity_in(capacity, alloc)?,
40        })
41    }
42
43    #[inline]
44    pub fn push(&mut self, value: T) -> Result<(), TryReserveError> {
45        self.reserve(1)?;
46        // SAFETY: we just reserved space for one more element.
47        unsafe {
48            self.unsafe_push(value);
49        }
50        Ok(())
51    }
52
53    #[inline]
54    unsafe fn unsafe_push(&mut self, value: T) {
55        let len = self.inner.len();
56        let end = self.inner.as_mut_ptr().add(len);
57        core::ptr::write(end, value);
58        self.inner.set_len(len + 1)
59    }
60
61    pub fn extend(&mut self, iter: impl IntoIterator<Item = T>) -> Result<(), TryReserveError> {
62        let mut iter = iter.into_iter();
63        let (lower_bound, _) = iter.size_hint();
64
65        // Extend N with pre-allocation from the iterator
66        self.reserve(lower_bound)?;
67        for _ in 0..lower_bound {
68            let Some(value) = iter.next() else {
69                return Ok(());
70            };
71            unsafe {
72                self.unsafe_push(value);
73            }
74        }
75
76        // Dynamically append the rest
77        for value in iter {
78            self.push(value)?;
79        }
80        Ok(())
81    }
82
83    #[inline]
84    pub fn iter(&self) -> core::slice::Iter<'_, T> {
85        self.inner.iter()
86    }
87
88    #[inline]
89    pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, T> {
90        self.inner.iter_mut()
91    }
92
93    #[inline]
94    pub fn len(&self) -> usize {
95        self.inner.len()
96    }
97
98    #[inline]
99    pub fn is_empty(&self) -> bool {
100        self.inner.is_empty()
101    }
102
103    #[inline]
104    pub fn as_slice(&self) -> &[T] {
105        self
106    }
107
108    #[inline]
109    pub fn as_ptr(&self) -> *const T {
110        self.inner.as_ptr()
111    }
112
113    #[inline]
114    pub fn as_mut_ptr(&mut self) -> *mut T {
115        self.inner.as_mut_ptr()
116    }
117
118    /// # Safety
119    ///
120    /// - `new_len` must be less than or equal to [`capacity()`].
121    ///
122    /// [`capacity()`]: Self::capacity
123    #[inline]
124    pub unsafe fn set_len(&mut self, new_len: usize) {
125        self.inner.set_len(new_len);
126    }
127
128    #[inline]
129    pub fn clear(&mut self) {
130        self.inner.clear();
131    }
132
133    #[inline]
134    pub fn truncate(&mut self, new_len: usize) {
135        self.inner.truncate(new_len);
136    }
137
138    #[inline]
139    pub fn resize_with<F: FnMut() -> T>(
140        &mut self,
141        new_len: usize,
142        mut f: F,
143    ) -> Result<(), TryReserveError> {
144        let len = self.len();
145        if new_len > len {
146            self.reserve(new_len - len)?;
147            for index in len..new_len {
148                unsafe {
149                    let end = self.inner.as_mut_ptr().add(index);
150                    core::ptr::write(end, f());
151                }
152            }
153            unsafe { self.inner.set_len(new_len) }
154        } else {
155            self.truncate(new_len);
156        }
157        Ok(())
158    }
159
160    pub(crate) fn into_inner(self) -> InnerVec<T, A> {
161        self.inner
162    }
163}
164
165impl<T: Claim, A: Allocator> Vec<T, A> {
166    #[inline]
167    pub fn extend_from_slice(&mut self, slice: &[T]) -> Result<(), TryReserveError> {
168        self.reserve(slice.len())?;
169
170        // Yes, we re-evaluate the capacity by delegating to the inner Vec,
171        // but we also gain the optimizations available via specific implementations
172        // for anything that supports the `Copy` trait.
173        self.inner.extend_from_slice(slice);
174        Ok(())
175    }
176
177    #[inline]
178    pub fn extend_with(&mut self, additional: usize, value: T) -> Result<(), TryReserveError> {
179        self.reserve(additional)?;
180        let len = self.inner.len();
181        let new_len = len + additional;
182        for index in len..new_len {
183            unsafe {
184                let end = self.inner.as_mut_ptr().add(index);
185                core::ptr::write(end, value.clone());
186            }
187        }
188        unsafe { self.inner.set_len(new_len) }
189        Ok(())
190    }
191
192    #[inline]
193    pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), TryReserveError> {
194        let len = self.len();
195        if new_len > len {
196            self.extend_with(new_len - len, value)?;
197        } else {
198            self.truncate(new_len);
199        }
200        Ok(())
201    }
202}
203
204impl<T: Claim, A: Allocator + Claim> TryClone for Vec<T, A> {
205    type Error = TryReserveError;
206
207    fn try_clone(&self) -> Result<Self, Self::Error> {
208        let mut cloned = Self::with_capacity_in(self.len(), self.allocator().clone())?;
209        cloned.extend_from_slice(self.inner.as_slice())?;
210        Ok(cloned)
211    }
212}
213
214impl<T, I: SliceIndex<[T]>, A: Allocator> Index<I> for Vec<T, A> {
215    type Output = I::Output;
216
217    #[inline]
218    fn index(&self, index: I) -> &Self::Output {
219        self.inner.index(index)
220    }
221}
222
223impl<T, I: SliceIndex<[T]>, A: Allocator> IndexMut<I> for Vec<T, A> {
224    #[inline]
225    fn index_mut(&mut self, index: I) -> &mut Self::Output {
226        self.inner.index_mut(index)
227    }
228}
229
230impl<T, A: Allocator> Deref for Vec<T, A> {
231    type Target = [T];
232
233    fn deref(&self) -> &Self::Target {
234        &self.inner
235    }
236}
237
238impl<T, A: Allocator> DerefMut for Vec<T, A> {
239    fn deref_mut(&mut self) -> &mut Self::Target {
240        &mut self.inner
241    }
242}
243
244impl<T: Debug, A: Allocator> Debug for Vec<T, A> {
245    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
246        self.inner.fmt(f)
247    }
248}
249
250macro_rules! __impl_slice_eq1 {
251    ([$($vars:tt)*] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?) => {
252        impl<T, U, $($vars)*> PartialEq<$rhs> for $lhs
253        where
254            T: PartialEq<U>,
255            $($ty: $bound)?
256        {
257            #[inline]
258            fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] }
259
260            #[allow(clippy::partialeq_ne_impl)]
261            #[inline]
262            fn ne(&self, other: &$rhs) -> bool { self[..] != other[..] }
263        }
264    }
265}
266
267__impl_slice_eq1! { [A1: Allocator, A2: Allocator] Vec<T, A1>, Vec<U, A2> }
268__impl_slice_eq1! { [A: Allocator] Vec<T, A>, &[U] }
269__impl_slice_eq1! { [A: Allocator] Vec<T, A>, &mut [U] }
270__impl_slice_eq1! { [A: Allocator] &[T], Vec<U, A> }
271__impl_slice_eq1! { [A: Allocator] &mut [T], Vec<U, A> }
272__impl_slice_eq1! { [A: Allocator] Vec<T, A>, [U] }
273__impl_slice_eq1! { [A: Allocator] [T], Vec<U, A> }
274__impl_slice_eq1! { [A: Allocator, const N: usize] Vec<T, A>, [U; N] }
275__impl_slice_eq1! { [A: Allocator, const N: usize] [T; N], Vec<U, A> }
276__impl_slice_eq1! { [A: Allocator, const N: usize] Vec<T, A>, &[U; N] }
277__impl_slice_eq1! { [A: Allocator, const N: usize] &[T; N], Vec<U, A> }
278
279impl<T, A: Allocator> AsRef<Vec<T, A>> for Vec<T, A> {
280    fn as_ref(&self) -> &Vec<T, A> {
281        self
282    }
283}
284
285impl<T, A: Allocator> AsMut<Vec<T, A>> for Vec<T, A> {
286    fn as_mut(&mut self) -> &mut Vec<T, A> {
287        self
288    }
289}
290
291impl<T, A: Allocator> AsRef<[T]> for Vec<T, A> {
292    fn as_ref(&self) -> &[T] {
293        self
294    }
295}
296
297impl<T, A: Allocator> AsMut<[T]> for Vec<T, A> {
298    fn as_mut(&mut self) -> &mut [T] {
299        self
300    }
301}
302
303#[cfg(test)]
304mod tests {
305    use super::*;
306    use crate::claim::Claim;
307    use crate::testing::{AllowGlobalAllocGuard, NoGlobalAllocGuard};
308    use crate::testing::{WatermarkAllocator, WatermarkAllocator2};
309    use alloc::boxed::Box;
310    use alloc::collections::TryReserveError;
311    use alloc::{format, vec};
312
313    #[test]
314    fn test_basics() {
315        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
316        let wma = WatermarkAllocator::new(32);
317        let mut vec = Vec::new_in(wma.clone());
318        assert_eq!(vec.len(), 0);
319        assert_eq!(vec.capacity(), 0);
320        assert!(vec.is_empty());
321        vec.push(1).unwrap();
322        assert_eq!(vec.len(), 1);
323        assert!(!vec.is_empty());
324        vec.push(2).unwrap();
325        vec.push(3).unwrap();
326        vec.push(4).unwrap();
327        assert_eq!(vec.len(), 4);
328        assert_eq!(vec.capacity(), 4);
329        assert_eq!(wma.in_use(), vec.capacity() * size_of::<i32>());
330        assert_eq!(vec.allocator().in_use(), vec.capacity() * size_of::<i32>());
331        let _err: TryReserveError = vec.push(5).unwrap_err();
332        assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
333        assert_eq!(vec.len(), 4);
334        vec.clear();
335        assert_eq!(vec.len(), 0);
336        assert!(vec.is_empty());
337        assert_eq!(vec.capacity(), 4);
338    }
339
340    #[test]
341    fn test_with_capacity_in() {
342        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
343        let wma = WatermarkAllocator::new(32);
344        let vec: Vec<usize, _> = Vec::with_capacity_in(4, wma.clone()).unwrap();
345        assert_eq!(vec.len(), 0);
346        assert_eq!(vec.as_slice(), &[]);
347        assert_eq!(vec.inner.capacity(), 4);
348        assert_eq!(wma.in_use(), 4 * size_of::<usize>());
349
350        let _err: TryReserveError = Vec::<i8, _>::with_capacity_in(5, wma).unwrap_err();
351    }
352
353    #[test]
354    fn test_reserve() {
355        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
356        let wma = WatermarkAllocator::new(32);
357        let mut vec: Vec<bool, _> = Vec::new_in(wma);
358        vec.reserve(32).unwrap();
359        assert_eq!(vec.inner.capacity(), 32);
360
361        let _err: TryReserveError = vec.reserve(33).unwrap_err();
362    }
363
364    #[test]
365    fn test_fmt_debug() {
366        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
367        let wma = WatermarkAllocator::new(32);
368        let mut vec = Vec::new_in(wma);
369        vec.push(1).unwrap();
370        vec.push(2).unwrap();
371        vec.push(3).unwrap();
372        vec.push(4).unwrap();
373        {
374            let _allow_global_alloc = AllowGlobalAllocGuard::new();
375            assert_eq!(format!("{:?}", vec), "[1, 2, 3, 4]");
376        }
377    }
378
379    #[test]
380    fn test_iter() {
381        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
382        let wma = WatermarkAllocator::new(32);
383        let mut vec = Vec::new_in(wma);
384        vec.push(1).unwrap();
385        vec.push(2).unwrap();
386        vec.push(3).unwrap();
387        vec.push(4).unwrap();
388        let mut iter = vec.iter();
389        assert_eq!(iter.next(), Some(&1));
390        assert_eq!(iter.next(), Some(&2));
391        assert_eq!(iter.next(), Some(&3));
392        assert_eq!(iter.next(), Some(&4));
393        assert_eq!(iter.next(), None);
394    }
395
396    #[test]
397    fn test_iter_mut() {
398        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
399        let wma = WatermarkAllocator::new(32);
400        let mut vec = Vec::new_in(wma);
401        vec.push(1).unwrap();
402        vec.push(2).unwrap();
403        vec.push(3).unwrap();
404        vec.push(4).unwrap();
405        let mut iter = vec.iter_mut();
406        assert_eq!(iter.next(), Some(&mut 1));
407        assert_eq!(iter.next(), Some(&mut 2));
408        assert_eq!(iter.next(), Some(&mut 3));
409        assert_eq!(iter.next(), Some(&mut 4));
410        assert_eq!(iter.next(), None);
411    }
412
413    #[test]
414    fn test_as_ptr() {
415        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
416        let wma = WatermarkAllocator::new(32);
417        let mut vec = Vec::new_in(wma.clone());
418        assert_eq!(wma.in_use(), 0);
419        vec.push(1).unwrap();
420        vec.push(2).unwrap();
421        vec.push(3).unwrap();
422        vec.push(4).unwrap();
423        let ptr = vec.as_ptr();
424        unsafe {
425            assert_eq!(*ptr, 1);
426            assert_eq!(*ptr.add(1), 2);
427            assert_eq!(*ptr.add(2), 3);
428            assert_eq!(*ptr.add(3), 4);
429        }
430    }
431
432    #[test]
433    fn test_as_mut_ptr() {
434        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
435        let wma = WatermarkAllocator::new(64);
436        let mut vec = Vec::new_in(wma.clone());
437        assert_eq!(wma.in_use(), 0);
438        vec.push('a').unwrap();
439        vec.push('b').unwrap();
440        vec.push('c').unwrap();
441        vec.push('d').unwrap();
442        vec.push('e').unwrap();
443        vec.push('f').unwrap();
444        let ptr = vec.as_mut_ptr();
445        unsafe {
446            assert_eq!(*ptr, 'a');
447            assert_eq!(*ptr.add(1), 'b');
448            assert_eq!(*ptr.add(2), 'c');
449            assert_eq!(*ptr.add(3), 'd');
450            assert_eq!(*ptr.add(4), 'e');
451            assert_eq!(*ptr.add(5), 'f');
452        }
453    }
454
455    #[test]
456    fn test_index() {
457        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
458        let wma = WatermarkAllocator::new(32);
459        let mut vec = Vec::new_in(wma);
460        vec.push(1).unwrap();
461        vec.push(2).unwrap();
462        vec.push(3).unwrap();
463        vec.push(4).unwrap();
464        assert_eq!(vec[0], 1);
465        assert_eq!(vec[1], 2);
466        assert_eq!(vec[2], 3);
467        assert_eq!(vec[3], 4);
468    }
469
470    /// A type that implements `Clone` and `Claim`, but not `Copy`.
471    #[derive(Clone, Eq, PartialEq)]
472    struct Claimable(i32);
473
474    impl Claim for Claimable {}
475
476    #[test]
477    fn test_extend_from_slice_clone() {
478        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
479        let wma = WatermarkAllocator::new(32);
480        let mut vec = Vec::new_in(wma);
481        vec.extend_from_slice(&[Claimable(1), Claimable(2), Claimable(3), Claimable(4)])
482            .unwrap();
483    }
484
485    #[test]
486    fn test_extend_from_slice_copy() {
487        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
488        let wma = WatermarkAllocator::new(32);
489        let mut vec = Vec::new_in(wma);
490        vec.extend_from_slice(&[1, 2, 3, 4]).unwrap();
491        assert_eq!(vec.inner.as_slice(), &[1, 2, 3, 4]);
492
493        let _err: TryReserveError = vec.extend_from_slice(&[5, 6]).unwrap_err();
494
495        vec.extend_from_slice(&[]).unwrap();
496    }
497
498    #[test]
499    fn test_deref() {
500        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
501        let wma = WatermarkAllocator::new(32);
502        let mut vec = Vec::new_in(wma);
503        vec.push(1).unwrap();
504        vec.push(2).unwrap();
505        vec.push(3).unwrap();
506        vec.push(4).unwrap();
507        assert_eq!(&*vec, &[1, 2, 3, 4]);
508    }
509
510    #[test]
511    fn test_deref_mut() {
512        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
513        let wma = WatermarkAllocator::new(32);
514        let mut vec = Vec::new_in(wma);
515        vec.push(1).unwrap();
516        vec.push(2).unwrap();
517        vec.push(3).unwrap();
518        vec.push(4).unwrap();
519        let vec: &mut [i32] = &mut vec;
520        vec[0] = 5;
521        vec[1] = 6;
522        vec[2] = 7;
523        vec[3] = 8;
524        assert_eq!(&*vec, &[5, 6, 7, 8]);
525    }
526
527    struct MyIter {
528        counter: usize,
529        min_size_hint: usize,
530    }
531
532    impl MyIter {
533        fn new(min_size_hint: usize) -> Self {
534            Self {
535                counter: 0,
536                min_size_hint,
537            }
538        }
539    }
540
541    impl Iterator for MyIter {
542        type Item = usize;
543
544        fn next(&mut self) -> Option<Self::Item> {
545            if self.counter >= 10 {
546                return None;
547            }
548            self.counter += 1;
549            Some(self.counter - 1)
550        }
551
552        // This sort-of lies, but it's here for testing purposes.
553        // It states that the iterator has at least, just, 5 elements.
554        // This is done so we can get good code coverage and test both
555        // the optimised pre-reserve code path for `extend` and the
556        // slower dynamic re-allocation code path.
557        fn size_hint(&self) -> (usize, Option<usize>) {
558            (self.min_size_hint, None)
559        }
560    }
561
562    #[test]
563    fn test_extend() {
564        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
565
566        // Test the optimised with mixed pre-reserved and dynamic allocation extend paths.
567        let wma = WatermarkAllocator::new(32 * size_of::<usize>());
568        {
569            let mut vec = Vec::new_in(wma.clone());
570            vec.extend(MyIter::new(5)).unwrap();
571            assert_eq!(vec.inner.as_slice(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
572        }
573        assert_eq!(wma.in_use(), 0);
574
575        // Test with a fully pre-reserved path.
576        {
577            let mut vec = Vec::new_in(wma.clone());
578            vec.extend(MyIter::new(10)).unwrap();
579            assert_eq!(vec.inner.as_slice(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
580        }
581        assert_eq!(wma.in_use(), 0);
582
583        // Test with a fully pre-reserved path, but the `min` size_hint lies
584        // and exceeds the truth.
585        {
586            let mut vec = Vec::new_in(wma.clone());
587            vec.extend(MyIter::new(20)).unwrap();
588            assert_eq!(vec.inner.as_slice(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
589        }
590        assert_eq!(wma.in_use(), 0);
591
592        // The min size hint is zero, all dynamically allocated.
593        {
594            let mut vec = Vec::new_in(wma.clone());
595            vec.extend(MyIter::new(0)).unwrap();
596            assert_eq!(vec.inner.as_slice(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
597        }
598        assert_eq!(wma.in_use(), 0);
599    }
600
601    #[test]
602    fn test_truncate() {
603        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
604        let wma = WatermarkAllocator::new(32);
605        let mut vec = Vec::new_in(wma);
606        vec.push(1).unwrap();
607        vec.push(2).unwrap();
608        vec.push(3).unwrap();
609        vec.push(4).unwrap();
610        vec.truncate(2);
611        assert_eq!(vec.inner.as_slice(), &[1, 2]);
612        vec.truncate(0);
613        let empty: &[i32] = &[];
614        assert_eq!(vec.inner.as_slice(), empty);
615    }
616
617    #[test]
618    fn test_extend_with() {
619        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
620        let wma = WatermarkAllocator::new(32);
621        let mut vec = Vec::new_in(wma);
622        vec.extend_with(3, 1).unwrap();
623        assert_eq!(vec.inner.as_slice(), &[1, 1, 1]);
624    }
625
626    #[test]
627    fn test_resize() {
628        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
629        let wma = WatermarkAllocator::new(64);
630        let mut vec = Vec::new_in(wma);
631        vec.resize(3, 1).unwrap();
632        assert_eq!(vec.inner.as_slice(), &[1, 1, 1]);
633        vec.resize(5, 2).unwrap();
634        assert_eq!(vec.inner.as_slice(), &[1, 1, 1, 2, 2]);
635        vec.resize(2, 3).unwrap();
636        assert_eq!(vec.inner.as_slice(), &[1, 1]);
637    }
638
639    #[test]
640    fn test_resize_with() {
641        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
642        let wma = WatermarkAllocator::new(64);
643        let mut vec = Vec::new_in(wma);
644        vec.resize_with(3, || 1).unwrap();
645        assert_eq!(vec.inner.as_slice(), &[1, 1, 1]);
646        vec.resize_with(5, || 2).unwrap();
647        assert_eq!(vec.inner.as_slice(), &[1, 1, 1, 2, 2]);
648        vec.resize_with(2, || 3).unwrap();
649        assert_eq!(vec.inner.as_slice(), &[1, 1]);
650    }
651
652    #[derive(PartialEq, Debug)]
653    struct IntWrapper(pub i32);
654
655    impl PartialEq<i32> for IntWrapper {
656        fn eq(&self, other: &i32) -> bool {
657            self.0 == *other
658        }
659    }
660
661    impl PartialEq<IntWrapper> for i32 {
662        fn eq(&self, other: &IntWrapper) -> bool {
663            self == &other.0
664        }
665    }
666
667    fn w(i: i32) -> IntWrapper {
668        IntWrapper(i)
669    }
670
671    #[test]
672    fn test_eq() {
673        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
674        let wma = WatermarkAllocator::new(64);
675        let wma2 = WatermarkAllocator2::new(1024);
676
677        // __impl_slice_eq1! { [A1: Allocator, A2: Allocator] Vec<T, A1>, Vec<U, A2> }
678        {
679            let mut lhs = Vec::new_in(wma.clone());
680            let mut rhs = Vec::new_in(wma2);
681
682            lhs.extend([1, 2, 3]).unwrap();
683            rhs.extend([w(1), w(2), w(3)]).unwrap();
684            assert_eq!(lhs, rhs);
685            assert_eq!(rhs, lhs);
686
687            rhs.push(w(4)).unwrap();
688            assert_ne!(lhs, rhs);
689            assert_ne!(rhs, lhs);
690        }
691
692        // __impl_slice_eq1! { [A: Allocator] Vec<T, A>, &[U] }
693        // __impl_slice_eq1! { [A: Allocator] &[T], Vec<U, A> }
694        {
695            let mut lhs = Vec::new_in(wma.clone());
696            lhs.extend([1, 2, 3]).unwrap();
697            let rhs: &[IntWrapper] = &[w(1), w(2), w(3)];
698            assert_eq!(lhs, rhs);
699            assert_eq!(rhs, lhs);
700
701            let rhs2: &[IntWrapper] = &[w(1), w(2), w(3), w(4)];
702            assert_ne!(lhs, rhs2);
703            assert_ne!(rhs2, lhs);
704        }
705
706        // __impl_slice_eq1! { [A: Allocator] Vec<T, A>, &mut [U] }
707        // __impl_slice_eq1! { [A: Allocator] &mut [T], Vec<U, A> }
708        {
709            let mut lhs = Vec::new_in(wma.clone());
710            lhs.extend([1, 2, 3]).unwrap();
711
712            let mut rhs_vec = {
713                let _allow_global_alloc = AllowGlobalAllocGuard::new();
714                let mut v = vec![w(1), w(2), w(3)];
715                v.reserve(1);
716                v
717            };
718            let rhs: &mut [IntWrapper] = &mut rhs_vec;
719
720            assert_eq!(lhs, rhs);
721            assert_eq!(rhs, lhs);
722
723            rhs_vec.push(w(4));
724            let rhs2: &mut [IntWrapper] = &mut rhs_vec;
725            assert_ne!(lhs, rhs2);
726            assert_ne!(rhs2, lhs);
727
728            {
729                let _allow_global_alloc = AllowGlobalAllocGuard::new();
730                drop(rhs_vec)
731            }
732        }
733
734        // __impl_slice_eq1! { [A: Allocator] Vec<T, A>, [U] }
735        // __impl_slice_eq1! { [A: Allocator] [T], Vec<U, A> }
736        {
737            let mut lhs = Vec::new_in(wma.clone());
738            lhs.extend([1, 2, 3]).unwrap();
739
740            // We explicitly elide the `len` part here by using a box.
741            let (rhs, rhs2) = {
742                let _allow_global_alloc = AllowGlobalAllocGuard::new();
743                let rhs: Box<[IntWrapper]> = Box::new([w(1), w(2), w(3)]);
744                let rhs2: Box<[IntWrapper]> = Box::new([w(1), w(2), w(3), w(4)]);
745                (rhs, rhs2)
746            };
747            assert_eq!(lhs, *rhs);
748            assert_eq!(*rhs, lhs);
749
750            assert_ne!(lhs, *rhs2);
751            assert_ne!(*rhs2, lhs);
752
753            {
754                let _allow_global_alloc = AllowGlobalAllocGuard::new();
755                drop(rhs);
756                drop(rhs2);
757            }
758        }
759
760        // __impl_slice_eq1! { [A: Allocator, const N: usize] Vec<T, A>, [U; N] }
761        // __impl_slice_eq1! { [A: Allocator, const N: usize] [T; N], Vec<U, A> }
762        {
763            let mut lhs = Vec::new_in(wma.clone());
764            lhs.extend([1, 2, 3]).unwrap();
765
766            let rhs: [IntWrapper; 3] = [w(1), w(2), w(3)];
767            assert_eq!(lhs, rhs); // Compare Vec with fixed-size array
768            assert_eq!(rhs, lhs); // Compare fixed-size array with Vec
769
770            let rhs2: [IntWrapper; 4] = [w(1), w(2), w(3), w(4)];
771            assert_ne!(lhs, rhs2); // Compare Vec with longer array
772            assert_ne!(rhs2, lhs); // Compare longer array with Vec
773        }
774
775        // __impl_slice_eq1! { [A: Allocator, const N: usize] Vec<T, A>, &[U; N] }
776        // __impl_slice_eq1! { [A: Allocator, const N: usize] &[T; N], Vec<U, A> }
777        {
778            let mut lhs = Vec::new_in(wma.clone());
779            lhs.extend([1, 2, 3]).unwrap();
780
781            let rhs_arr: [IntWrapper; 3] = [w(1), w(2), w(3)];
782            let rhs: &[IntWrapper; 3] = &rhs_arr;
783            assert_eq!(lhs, rhs);
784            assert_eq!(rhs, lhs);
785
786            lhs.push(4).unwrap();
787            assert_ne!(lhs, rhs);
788            assert_ne!(rhs, lhs);
789        }
790    }
791
792    fn get_first_elem_vec<T: Claim, A: Allocator>(vec: impl AsRef<Vec<T, A>>) -> T {
793        let vec = vec.as_ref();
794        vec.first().unwrap().clone()
795    }
796
797    fn get_first_elem_slice<T: Claim>(slice: impl AsRef<[T]>) -> T {
798        let vec = slice.as_ref();
799        vec.first().unwrap().clone()
800    }
801
802    #[test]
803    fn test_as_ref() {
804        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
805        let wma = WatermarkAllocator::new(128);
806        let mut vec1 = Vec::new_in(wma);
807        vec1.extend([1, 2, 3]).unwrap();
808        let vec2 = vec1.try_clone().unwrap();
809
810        assert_eq!(vec1, vec2);
811        let e0vec1 = get_first_elem_vec(vec1);
812        let e0vec2 = get_first_elem_slice(vec2);
813        assert_eq!(e0vec1, 1);
814        assert_eq!(e0vec2, 1);
815    }
816
817    fn doubled_first_elem_vec(mut vec: impl AsMut<Vec<i32, WatermarkAllocator>>) -> i32 {
818        let vec = vec.as_mut();
819        vec[0] *= 2;
820        vec[0]
821    }
822
823    fn doubled_first_elem_slice(mut vec: impl AsMut<[i32]>) -> i32 {
824        let vec = vec.as_mut();
825        vec[0] *= 2;
826        vec[0]
827    }
828
829    #[test]
830    fn test_as_mut() {
831        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
832        let wma = WatermarkAllocator::new(128);
833        let mut vec1 = Vec::new_in(wma);
834        vec1.extend([1, 2, 3]).unwrap();
835        let vec2 = vec1.try_clone().unwrap();
836        assert_eq!(vec1, vec2);
837
838        let d0vec1 = doubled_first_elem_vec(vec1);
839        let d0vec2 = doubled_first_elem_slice(vec2);
840
841        assert_eq!(d0vec1, 2);
842        assert_eq!(d0vec2, 2);
843    }
844
845    #[test]
846    fn test_try_clone() {
847        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
848        let wma = WatermarkAllocator::new(64);
849        let mut vec1 = Vec::new_in(wma.clone());
850        vec1.extend([1usize, 2, 3, 4, 5, 6, 7, 8]).unwrap();
851        assert_eq!(vec1.len(), 8);
852        assert_eq!(vec1.capacity(), 8);
853        assert_eq!(wma.in_use(), 64);
854        assert!(vec1.try_clone().is_err());
855    }
856
857    #[test]
858    fn test_set_len() {
859        let _no_global_alloc_guard = NoGlobalAllocGuard::new();
860        let wma = WatermarkAllocator::new(64);
861        let mut vec: Vec<i32, _> = Vec::with_capacity_in(4, wma).unwrap();
862
863        // Write values directly to the buffer
864        let ptr = vec.as_mut_ptr();
865        unsafe {
866            ptr.write(1);
867            ptr.add(1).write(2);
868            ptr.add(2).write(3);
869            // Now set the length to match initialized elements
870            vec.set_len(3);
871        }
872
873        assert_eq!(vec.len(), 3);
874        assert_eq!(vec.as_slice(), &[1, 2, 3]);
875    }
876}