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
use std::{ops,mem,marker,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,
}
unsafe fn as_ptr<T: ?Sized, D: ::DataBuf>(s: &ValueA<T, D>) -> *mut T {
let mut ret: *const T = mem::uninitialized();
{
let ret_as_slice = super::ptr_as_slice(&mut ret);
let data = s.data.as_ref();
ret_as_slice[0] = data[..].as_ptr() as usize;
let info_size = ret_as_slice.len() - 1;
let info_ofs = data.len() - info_size;
for i in 0 .. info_size {
ret_as_slice[1+i] = data[info_ofs + i];
}
}
ret as *mut _
}
impl<T: ?Sized, D: ::DataBuf> ValueA<T, D>
{
pub fn new<U: marker::Unsize<T>>(val: U) -> Result<ValueA<T,D>,U> {
let rv = unsafe {
let mut ptr: *const T = &val as &T;
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)
},
}
}
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() + (size + mem::size_of::<usize>() - 1) / mem::size_of::<usize>() <= 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.offset(i as isize) = *src_ptr.offset(i as isize);
}
Some(rv)
}
}
}
impl<T: ?Sized, D: ::DataBuf> ops::Deref for ValueA<T, D> {
type Target = T;
fn deref(&self) -> &T {
unsafe {
&*as_ptr(self)
}
}
}
impl<T: ?Sized, D: ::DataBuf> ops::DerefMut for ValueA<T, D> {
fn deref_mut(&mut self) -> &mut T {
unsafe {
&mut *as_ptr(self)
}
}
}
impl<T: ?Sized, D: ::DataBuf> ops::Drop for ValueA<T, D> {
fn drop(&mut self) {
unsafe {
ptr::drop_in_place(&mut **self)
}
}
}