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
#![no_std]
use core::{cell::UnsafeCell, convert::Infallible};
#[cfg(not(features = "no_std"))]
mod std {
use crate::IdMismatch;
extern crate std;
impl std::error::Error for IdMismatch {}
}
pub mod support;
pub use support::{IdMismatch, RuntimeToken, TokenChecker, TokenTrait};
#[repr(C)]
pub struct TokenCell<Token: TokenTrait, T> {
inner: UnsafeCell<T>,
checker: Token::Checker,
}
impl<Token: TokenTrait, T> TokenCell<Token, T>
where
Token::Checker: TokenChecker<Token, Error = Infallible>,
{
#[inline(always)]
pub fn borrow<'l>(&'l self, _: &'l Token) -> &'l T {
unsafe { &*self.inner.get() }
}
#[inline(always)]
pub fn borrow_mut<'l>(&'l self, _: &'l mut Token) -> &'l mut T {
unsafe { &mut *self.inner.get() }
}
#[inline(always)]
pub fn swap(&self, mut value: T, token: &mut Token) -> T {
core::mem::swap(self.borrow_mut(token), &mut value);
value
}
}
impl<Token: TokenTrait, T> TokenCell<Token, T> {
#[inline(always)]
pub fn new(value: T) -> Self
where
Token::Checker: TokenChecker<Token, Input = ()>,
{
TokenCell {
inner: UnsafeCell::new(value),
checker: TokenChecker::new(()),
}
}
#[inline(always)]
pub fn with_token(token: &Token, value: T) -> Self
where
Token::Checker: TokenChecker<Token>,
{
TokenCell {
inner: UnsafeCell::new(value),
checker: TokenChecker::from_ref(token),
}
}
#[inline(always)]
pub fn into_inner(self) -> T {
self.inner.into_inner()
}
#[inline(always)]
pub fn try_swap(
&self,
mut value: T,
token: &mut Token,
) -> Result<T, <Token::Checker as TokenChecker<Token>>::Error> {
core::mem::swap(self.try_borrow_mut(token)?, &mut value);
Ok(value)
}
#[inline(always)]
pub fn try_borrow<'l>(
&'l self,
token: &'l Token,
) -> Result<&'l T, <Token::Checker as TokenChecker<Token>>::Error> {
self.checker
.check(token)
.map(|_| unsafe { &*self.inner.get() })
}
#[inline(always)]
pub fn try_borrow_mut<'l>(
&'l self,
token: &'l mut Token,
) -> Result<&'l mut T, <Token::Checker as TokenChecker<Token>>::Error> {
self.checker
.check(token)
.map(|_| unsafe { &mut *self.inner.get() })
}
#[inline(always)]
pub fn as_ptr(&self) -> *mut T {
self.inner.get()
}
}
impl<Token: TokenTrait, T> AsMut<T> for TokenCell<Token, T> {
fn as_mut(&mut self) -> &mut T {
self.inner.get_mut()
}
}
unsafe impl<Token: TokenTrait, T: Send> Send for TokenCell<Token, T> {}
unsafe impl<Token: TokenTrait, T: Sync> Sync for TokenCell<Token, T> {}