1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use std::ops::{Placer, Place, InPlace, BoxPlace, Boxed};
use std::mem::forget;
use mbox::MBox;
use internal::{gen_malloc, gen_free};
#[cfg(test)] use internal::DropCounter;
pub const MALLOC: MallocPlacer = MallocPlacer(());
#[doc(hidden)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct MallocPlacer(());
#[doc(hidden)]
pub struct MPlace<T>(*mut T);
impl<T> Placer<T> for MallocPlacer {
type Place = MPlace<T>;
fn make_place(self) -> MPlace<T> {
unsafe {
MPlace(gen_malloc(1))
}
}
}
impl<T> Drop for MPlace<T> {
fn drop(&mut self) {
unsafe {
gen_free(self.0);
}
}
}
impl<T> Place<T> for MPlace<T> {
fn pointer(&mut self) -> *mut T {
self.0
}
}
impl<T> InPlace<T> for MPlace<T> {
type Owner = MBox<T>;
unsafe fn finalize(self) -> MBox<T> {
let result = MBox::from_raw(self.0);
forget(self);
result
}
}
impl<T> BoxPlace<T> for MPlace<T> {
fn make_place() -> MPlace<T> {
MALLOC.make_place()
}
}
impl<T> Boxed for MBox<T> {
type Data = T;
type Place = MPlace<T>;
unsafe fn finalize(filled: MPlace<T>) -> Self {
filled.finalize()
}
}
#[test]
fn test_in_place() {
let counter = DropCounter::default();
{
let mbox: MBox<DropCounter> = MALLOC <- counter.clone();
mbox.assert_eq(0);
counter.assert_eq(0);
}
counter.assert_eq(1);
}
#[test]
#[should_panic="should panic without crash"]
fn test_panic_during_construction() {
let _: MBox<DropCounter> = MALLOC <- panic!("should panic without crash");
}