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);