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
|
use std::alloc::{alloc, dealloc, handle_alloc_error, Layout};
use std::mem::MaybeUninit;
use std::ptr::NonNull;
pub trait MaybeUninitByteSlice
{
unsafe fn cast<Item: 'static>(&self) -> &[Item];
}
impl MaybeUninitByteSlice for &[MaybeUninit<u8>]
{
unsafe fn cast<Item: 'static>(&self) -> &[Item]
{
assert_eq!(self.len() % size_of::<Item>(), 0, "Invalid item size");
assert_eq!(
self.as_ptr().addr() % align_of::<Item>(),
0,
"Invalid item alignment"
);
let new_len = self.len() / size_of::<Item>();
if new_len == 0 {
return &[];
}
unsafe { std::slice::from_raw_parts(self.as_ptr().cast::<Item>(), new_len) }
}
}
#[derive(Debug)]
pub struct AnonUnique
{
ptr: NonNull<MaybeUninit<u8>>,
layout: Layout,
}
impl AnonUnique
{
pub fn new_uninit(layout: Layout) -> Self
{
if layout.size() == 0 {
return Self { ptr: NonNull::dangling(), layout };
}
let Some(ptr) = NonNull::new(unsafe { alloc(layout) }) else {
handle_alloc_error(layout);
};
Self {
ptr: ptr.cast::<MaybeUninit<u8>>(),
layout,
}
}
pub fn as_slice_mut(&mut self) -> &mut [MaybeUninit<u8>]
{
unsafe { std::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.layout.size()) }
}
pub fn as_slice(&self) -> &[MaybeUninit<u8>]
{
unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.layout.size()) }
}
}
impl Drop for AnonUnique
{
fn drop(&mut self)
{
if self.layout.size() == 0 {
return;
}
unsafe {
dealloc(self.ptr.as_ptr().cast(), self.layout);
}
}
}
#[derive(Debug)]
pub enum Either<A, B>
{
A(A),
B(B),
}
impl<A, B> Either<A, B>
{
pub fn as_a(&self) -> Option<&A>
{
match self {
Self::A(a) => Some(a),
Self::B(_) => None,
}
}
}
|