-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathvery_unstable.rs
49 lines (43 loc) · 1.49 KB
/
very_unstable.rs
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
use core::ptr::NonNull;
use crate::VolatilePtr;
impl<'a, T, A> VolatilePtr<'a, T, A>
where
T: ?Sized,
{
/// Compile-time evaluable variant of [`Self::map`].
///
/// This function is a copy of [`Self::map`] that uses unstable compiler functions
/// to be callable from `const` contexts.
///
/// ## Safety
///
/// The safety requirements of [`Self::map`] apply to this method too.
pub const unsafe fn map_const<F, U>(self, f: F) -> VolatilePtr<'a, U, A>
where
F: FnOnce(NonNull<T>) -> NonNull<U>,
U: ?Sized,
{
unsafe { VolatilePtr::new_generic(f(self.pointer)) }
}
}
/// Methods for volatile slices
#[cfg(feature = "unstable")]
impl<'a, T, A> VolatilePtr<'a, [T], A> {
/// Compile-time evaluable variant of [`Self::index`].
///
/// This function is a copy of [`Self::index`] that uses unstable compiler functions
/// to be callable from `const` contexts.
pub const fn index_const(self, index: usize) -> VolatilePtr<'a, T, A> {
assert!(index < self.pointer.len(), "index out of bounds");
struct Mapper {
index: usize,
}
impl<T> FnOnce<(NonNull<[T]>,)> for Mapper {
type Output = NonNull<T>;
extern "rust-call" fn call_once(self, (slice,): (NonNull<[T]>,)) -> Self::Output {
unsafe { NonNull::new_unchecked(slice.as_non_null_ptr().as_ptr().add(self.index)) }
}
}
unsafe { self.map_const(Mapper { index }) }
}
}