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
use std::{
io::IoSlice,
mem::{ManuallyDrop, MaybeUninit},
num::NonZeroUsize,
ptr::NonNull,
slice::{from_raw_parts, from_raw_parts_mut},
};
#[derive(Debug)]
pub struct ReusableIoSlices {
ptr: NonNull<()>,
cap: NonZeroUsize,
}
unsafe impl Send for ReusableIoSlices {}
unsafe impl Sync for ReusableIoSlices {}
impl ReusableIoSlices {
pub fn new(cap: NonZeroUsize) -> Self {
let mut v = ManuallyDrop::new(Vec::<MaybeUninit<IoSlice<'_>>>::with_capacity(cap.get()));
debug_assert_eq!(v.capacity(), cap.get());
debug_assert_eq!(v.len(), 0);
let ptr = v.as_mut_ptr();
let ptr = unsafe { NonNull::new_unchecked(ptr as *mut ()) };
Self { ptr, cap }
}
pub fn get_mut(&mut self) -> &mut [MaybeUninit<IoSlice<'_>>] {
unsafe {
from_raw_parts_mut(
self.ptr.as_ptr() as *mut MaybeUninit<IoSlice<'_>>,
self.cap.get(),
)
}
}
pub fn get(&self) -> &[MaybeUninit<IoSlice<'_>>] {
unsafe {
from_raw_parts(
self.ptr.as_ptr() as *const MaybeUninit<IoSlice<'_>>,
self.cap.get(),
)
}
}
}
impl Drop for ReusableIoSlices {
fn drop(&mut self) {
let ptr = self.ptr.as_ptr() as *mut MaybeUninit<IoSlice<'_>>;
let v: Vec<MaybeUninit<IoSlice<'_>>> =
unsafe { Vec::from_raw_parts(ptr, 0, self.cap.get()) };
drop(v);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_reusable_io_slices() {
let io_slice = IoSlice::new(b"123exr3x");
for size in 1..300 {
let cap = NonZeroUsize::new(size).unwrap();
let mut reusable_io_slices = ReusableIoSlices::new(cap);
for uninit_io_slice in reusable_io_slices.get_mut() {
uninit_io_slice.write(io_slice);
}
}
}
}