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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
use std::{marker, mem, ops, ptr};
pub const DEFAULT_SIZE: usize = 8 + 1;
pub type Value<T > = ValueA<T, [usize; DEFAULT_SIZE]>;
pub struct ValueA<T: ?Sized, D: ::DataBuf> {
_align: [u64; 0],
_pd: marker::PhantomData<T>,
data: D,
}
impl<T: ?Sized, D: ::DataBuf> ValueA<T, D> {
#[cfg(feature = "unsize")]
pub fn new<U: marker::Unsize<T>>(val: U) -> Result<ValueA<T, D>, U> {
Self::new_stable(val, |p| p)
}
pub fn new_stable<U, F: FnOnce(&U) -> &T>(val: U, get_ref: F) -> Result<ValueA<T, D>, U> {
let rv = unsafe {
let mut ptr: *const T = get_ref(&val);
assert_eq!(ptr as *const u8, &val as *const _ as *const u8, "MISUSE: Closure returned different pointer");
assert_eq!(mem::size_of_val(&*ptr), mem::size_of::<U>(), "MISUSE: Closure returned a subset pointer");
let words = super::ptr_as_slice(&mut ptr);
assert!(
words[0] == &val as *const _ as usize,
"BUG: Pointer layout is not (data_ptr, info...)"
);
assert!(
mem::align_of::<U>() <= mem::align_of::<Self>(),
"TODO: Enforce alignment >{} (requires {})",
mem::align_of::<Self>(),
mem::align_of::<U>()
);
ValueA::new_raw(&words[1..], words[0] as *mut (), mem::size_of::<U>())
};
match rv {
Some(r) => {
mem::forget(val);
Ok(r)
}
None => Err(val),
}
}
#[cfg(all(feature = "alloc", feature = "unsize"))]
pub fn new_or_boxed<U>(val: U) -> ValueA<T, D>
where
U: marker::Unsize<T>,
::alloc::boxed::Box<U>: marker::Unsize<T>,
{
Self::new(val).unwrap_or_else(|val| {
Self::new(Box::new(val))
.ok()
.expect("Insufficient space for Box<T>")
})
}
pub unsafe fn new_raw(info: &[usize], data: *mut (), size: usize) -> Option<ValueA<T, D>> {
if info.len() * mem::size_of::<usize>() + size > mem::size_of::<D>() {
None
} else {
let mut rv = ValueA {
_align: [],
_pd: marker::PhantomData,
data: D::default(),
};
assert!(info.len() + super::round_to_words(size) <= rv.data.as_ref().len());
{
let info_ofs = rv.data.as_ref().len() - info.len();
let info_dst = &mut rv.data.as_mut()[info_ofs..];
for (d, v) in Iterator::zip(info_dst.iter_mut(), info.iter()) {
*d = *v;
}
}
let src_ptr = data as *const u8;
let dataptr = rv.data.as_mut()[..].as_mut_ptr() as *mut u8;
for i in 0..size {
*dataptr.add(i) = *src_ptr.add(i);
}
Some(rv)
}
}
unsafe fn as_ptr(&self) -> *mut T {
let data = self.data.as_ref();
let info_size = mem::size_of::<*mut T>() / mem::size_of::<usize>() - 1;
let info_ofs = data.len() - info_size;
super::make_fat_ptr(data[..].as_ptr() as usize, &data[info_ofs..])
}
}
impl<T: ?Sized, D: ::DataBuf> ops::Deref for ValueA<T, D> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.as_ptr() }
}
}
impl<T: ?Sized, D: ::DataBuf> ops::DerefMut for ValueA<T, D> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.as_ptr() }
}
}
impl<T: ?Sized, D: ::DataBuf> ops::Drop for ValueA<T, D> {
fn drop(&mut self) {
unsafe { ptr::drop_in_place(&mut **self) }
}
}
mod trait_impls;