6 use crate::alloc::AllocError;
8 // Writing a test of integration between third-party
9 // allocators and `RawVec` is a little tricky because the `RawVec`
10 // API does not expose fallible allocation methods, so we
11 // cannot check what happens when allocator is exhausted
12 // (beyond detecting a panic).
14 // Instead, this just checks that the `RawVec` methods do at
15 // least go through the Allocator API when it reserves
18 // A dumb allocator that consumes a fixed amount of fuel
19 // before allocation attempts start failing.
23 unsafe impl Allocator for BoundedAlloc {
24 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
25 let size = layout.size();
26 if size > self.fuel.get() {
27 return Err(AllocError);
29 match Global.allocate(layout) {
31 self.fuel.set(self.fuel.get() - size);
37 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
38 unsafe { Global.deallocate(ptr, layout) }
42 let a = BoundedAlloc { fuel: Cell::new(500) };
43 let mut v: RawVec<u8, _> = RawVec::with_capacity_in(50, a);
44 assert_eq!(v.alloc.fuel.get(), 450);
45 v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel)
46 assert_eq!(v.alloc.fuel.get(), 250);
50 fn reserve_does_not_overallocate() {
52 let mut v: RawVec<u32> = RawVec::new();
53 // First, `reserve` allocates like `reserve_exact`.
55 assert_eq!(9, v.capacity());
59 let mut v: RawVec<u32> = RawVec::new();
61 assert_eq!(7, v.capacity());
62 // 97 is more than double of 7, so `reserve` should work
63 // like `reserve_exact`.
65 assert_eq!(97, v.capacity());
69 let mut v: RawVec<u32> = RawVec::new();
71 assert_eq!(12, v.capacity());
73 // 3 is less than half of 12, so `reserve` must grow
74 // exponentially. At the time of writing this test grow
75 // factor is 2, so new capacity is 24, however, grow factor
76 // of 1.5 is OK too. Hence `>= 18` in assert.
77 assert!(v.capacity() >= 12 + 12 / 2);
83 // A `RawVec` holding zero-sized elements should always look like this.
84 fn zst_sanity<T>(v: &RawVec<T>) {
85 assert_eq!(v.capacity(), usize::MAX);
86 assert_eq!(v.ptr(), core::ptr::Unique::<T>::dangling().as_ptr());
87 assert_eq!(v.current_memory(), None);
92 let cap_err = Err(crate::collections::TryReserveErrorKind::CapacityOverflow.into());
94 assert_eq!(std::mem::size_of::<ZST>(), 0);
96 // All these different ways of creating the RawVec produce the same thing.
98 let v: RawVec<ZST> = RawVec::new();
101 let v: RawVec<ZST> = RawVec::with_capacity_in(100, Global);
104 let v: RawVec<ZST> = RawVec::with_capacity_in(100, Global);
107 let v: RawVec<ZST> = RawVec::allocate_in(0, AllocInit::Uninitialized, Global);
110 let v: RawVec<ZST> = RawVec::allocate_in(100, AllocInit::Uninitialized, Global);
113 let mut v: RawVec<ZST> = RawVec::allocate_in(usize::MAX, AllocInit::Uninitialized, Global);
116 // Check all these operations work as expected with zero-sized elements.
118 assert!(!v.needs_to_grow(100, usize::MAX - 100));
119 assert!(v.needs_to_grow(101, usize::MAX - 100));
122 v.reserve(100, usize::MAX - 100);
123 //v.reserve(101, usize::MAX - 100); // panics, in `zst_reserve_panic` below
126 v.reserve_exact(100, usize::MAX - 100);
127 //v.reserve_exact(101, usize::MAX - 100); // panics, in `zst_reserve_exact_panic` below
130 assert_eq!(v.try_reserve(100, usize::MAX - 100), Ok(()));
131 assert_eq!(v.try_reserve(101, usize::MAX - 100), cap_err);
134 assert_eq!(v.try_reserve_exact(100, usize::MAX - 100), Ok(()));
135 assert_eq!(v.try_reserve_exact(101, usize::MAX - 100), cap_err);
138 assert_eq!(v.grow_amortized(100, usize::MAX - 100), cap_err);
139 assert_eq!(v.grow_amortized(101, usize::MAX - 100), cap_err);
142 assert_eq!(v.grow_exact(100, usize::MAX - 100), cap_err);
143 assert_eq!(v.grow_exact(101, usize::MAX - 100), cap_err);
148 #[should_panic(expected = "capacity overflow")]
149 fn zst_reserve_panic() {
150 let mut v: RawVec<ZST> = RawVec::new();
153 v.reserve(101, usize::MAX - 100);
157 #[should_panic(expected = "capacity overflow")]
158 fn zst_reserve_exact_panic() {
159 let mut v: RawVec<ZST> = RawVec::new();
162 v.reserve_exact(101, usize::MAX - 100);