]> git.proxmox.com Git - rustc.git/blob - library/alloc/src/raw_vec/tests.rs
New upstream version 1.50.0+dfsg1
[rustc.git] / library / alloc / src / raw_vec / tests.rs
1 use super::*;
2 use std::cell::Cell;
3
4 #[test]
5 fn allocator_param() {
6 use crate::alloc::AllocError;
7
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).
13 //
14 // Instead, this just checks that the `RawVec` methods do at
15 // least go through the Allocator API when it reserves
16 // storage.
17
18 // A dumb allocator that consumes a fixed amount of fuel
19 // before allocation attempts start failing.
20 struct BoundedAlloc {
21 fuel: Cell<usize>,
22 }
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);
28 }
29 match Global.allocate(layout) {
30 ok @ Ok(_) => {
31 self.fuel.set(self.fuel.get() - size);
32 ok
33 }
34 err @ Err(_) => err,
35 }
36 }
37 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
38 unsafe { Global.deallocate(ptr, layout) }
39 }
40 }
41
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);
47 }
48
49 #[test]
50 fn reserve_does_not_overallocate() {
51 {
52 let mut v: RawVec<u32> = RawVec::new();
53 // First, `reserve` allocates like `reserve_exact`.
54 v.reserve(0, 9);
55 assert_eq!(9, v.capacity());
56 }
57
58 {
59 let mut v: RawVec<u32> = RawVec::new();
60 v.reserve(0, 7);
61 assert_eq!(7, v.capacity());
62 // 97 is more than double of 7, so `reserve` should work
63 // like `reserve_exact`.
64 v.reserve(7, 90);
65 assert_eq!(97, v.capacity());
66 }
67
68 {
69 let mut v: RawVec<u32> = RawVec::new();
70 v.reserve(0, 12);
71 assert_eq!(12, v.capacity());
72 v.reserve(12, 3);
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);
78 }
79 }