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
use std::pin;
/// A fixed, dense allocation whose elements remain pinned until drop.
#[repr(transparent)]
pub struct Slice<T> {
entries: pin::Pin<Box<[T]>>,
}
impl<T> Slice<T> {
pub fn get(&self, index: usize) -> Option<pin::Pin<&T>> {
let entry = self.entries.as_ref().get_ref().get(index)?;
// SAFETY: Slice never exposes ownership of or mutable unpinned access
// to its boxed storage. The allocation remains pinned through the
// returned shared borrow, so this element cannot move or be replaced.
Some(unsafe { pin::Pin::new_unchecked(entry) })
}
pub fn iter<'a>(
&'a self,
) -> impl DoubleEndedIterator<Item = pin::Pin<&'a T>> + ExactSizeIterator + 'a
where
T: 'a,
{
self.entries.as_ref().get_ref().iter().map(|entry| {
// SAFETY: Slice never exposes ownership of or mutable unpinned
// access to its boxed storage. The allocation remains pinned
// through the returned shared borrow, so this element cannot move
// or be replaced.
unsafe { pin::Pin::new_unchecked(entry) }
})
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}
impl<T> From<Box<[T]>> for Slice<T> {
fn from(entries: Box<[T]>) -> Self {
Self {
entries: Box::into_pin(entries),
}
}
}
impl<T> FromIterator<T> for Slice<T> {
fn from_iter<I: IntoIterator<Item = T>>(entries: I) -> Self {
entries.into_iter().collect::<Box<[_]>>().into()
}
}