1use ::core::{
2 cell::UnsafeCell,
3 ops::{Deref, DerefMut},
4};
5
6trait MapLikely<T> {
7 type Output<U>;
8 fn map_likely<U, F: FnOnce(T) -> U>(self, f: F) -> Self::Output<U>;
9}
10#[cold]
11fn cold() {}
12impl<T, E> MapLikely<T> for Result<T, E> {
13 type Output<U> = Result<U, E>;
14 fn map_likely<U, F: FnOnce(T) -> U>(self, f: F) -> Self::Output<U> {
15 match self {
16 Ok(v) => Ok(f(v)),
17 Err(e) => {
18 cold();
19 Err(e)
20 }
21 }
22 }
23}
24
25use crate::monads::{TokenMap, TokenMapMut};
26pub trait TokenTrait: Sized {
28 type ConstructionError;
29 type RunError;
30 type Identifier;
31 type ComparisonError;
32 fn new() -> Result<Self, Self::ConstructionError>;
34 fn with_token<R, F: FnOnce(Self) -> R>(f: F) -> Result<R, Self::RunError>;
39 fn identifier(&self) -> Self::Identifier;
41 fn compare(&self, id: &Self::Identifier) -> Result<(), Self::ComparisonError>;
43}
44
45pub trait TokenCellTrait<T: ?Sized, Token: TokenTrait>: Sync {
46 fn new(inner: T, token: &Token) -> Self
48 where
49 T: Sized;
50 fn try_guard<'l>(
53 &'l self,
54 token: &'l Token,
55 ) -> Result<TokenGuard<'l, T, Token>, Token::ComparisonError>;
56 fn try_borrow<'l>(&'l self, token: &'l Token) -> Result<&'l T, Token::ComparisonError>;
60 fn try_guard_mut<'l>(
63 &'l self,
64 token: &'l mut Token,
65 ) -> Result<TokenGuardMut<'l, T, Token>, Token::ComparisonError>;
66 fn try_borrow_mut<'l>(
70 &'l self,
71 token: &'l mut Token,
72 ) -> Result<&'l mut T, Token::ComparisonError>;
73 fn borrow<'l>(&'l self, token: &'l Token) -> &'l T
75 where
76 Token::ComparisonError: core::fmt::Debug,
77 {
78 self.try_borrow(token).unwrap()
79 }
80 fn borrow_mut<'l>(&'l self, token: &'l mut Token) -> &'l mut T
82 where
83 Token::ComparisonError: core::fmt::Debug,
84 {
85 self.try_borrow_mut(token).unwrap()
86 }
87 fn map<'a, U, F: FnOnce(TokenGuard<'a, T, Token>) -> U>(
89 &'a self,
90 f: F,
91 ) -> TokenMap<'a, T, U, F, Self, Token> {
92 TokenMap {
93 cell: self,
94 f,
95 marker: core::marker::PhantomData,
96 }
97 }
98 fn map_mut<'a, U, F: FnOnce(TokenGuardMut<'a, T, Token>) -> U>(
100 &'a self,
101 f: F,
102 ) -> TokenMapMut<'a, T, U, F, Self, Token> {
103 TokenMapMut {
104 cell: self,
105 f,
106 marker: core::marker::PhantomData,
107 }
108 }
109}
110
111pub struct TokenGuard<'a, T: ?Sized, Token: TokenTrait> {
112 cell: &'a TokenCell<T, Token>,
113 token: &'a Token,
114}
115impl<'a, T: ?Sized, Token: TokenTrait> TokenGuard<'a, T, Token> {
116 pub fn token(&'a self) -> &'a Token {
117 self.token
118 }
119}
120impl<'a, T: ?Sized, Token: TokenTrait> Deref for TokenGuard<'a, T, Token> {
121 type Target = T;
122 fn deref(&self) -> &Self::Target {
123 unsafe { &*self.cell.inner.get() }
124 }
125}
126
127pub struct TokenGuardMut<'a, T: ?Sized, Token: TokenTrait> {
128 cell: &'a TokenCell<T, Token>,
129 token: &'a mut Token,
130}
131impl<'a, T: ?Sized, Token: TokenTrait> TokenGuardMut<'a, T, Token> {
132 pub fn token(&'a self) -> &'a Token {
133 self.token
134 }
135 pub fn token_mut(&'a mut self) -> &'a mut Token {
136 self.token
137 }
138}
139impl<'a, T: ?Sized, Token: TokenTrait> Deref for TokenGuardMut<'a, T, Token> {
140 type Target = T;
141 fn deref(&self) -> &Self::Target {
142 unsafe { &*self.cell.inner.get() }
143 }
144}
145impl<'a, T, Token: TokenTrait> core::ops::DerefMut for TokenGuardMut<'a, T, Token> {
146 fn deref_mut(&mut self) -> &mut Self::Target {
147 unsafe { &mut *self.cell.inner.get() }
148 }
149}
150
151pub struct TokenCell<T: ?Sized, Token: TokenTrait> {
153 token_id: Token::Identifier,
154 inner: UnsafeCell<T>,
155}
156impl<T: ?Sized, Token: TokenTrait> TokenCell<T, Token> {
157 pub fn get_mut(&mut self) -> &mut T {
158 self.inner.get_mut()
159 }
160}
161impl<T: Sized, Token: TokenTrait> TokenCell<T, Token> {
162 pub fn into_inner(self) -> T {
163 self.inner.into_inner()
164 }
165}
166impl<T: ?Sized, Token: TokenTrait> Deref for TokenCell<T, Token> {
167 type Target = UnsafeCell<T>;
168 fn deref(&self) -> &Self::Target {
169 &self.inner
170 }
171}
172impl<T: ?Sized, Token: TokenTrait> DerefMut for TokenCell<T, Token> {
173 fn deref_mut(&mut self) -> &mut Self::Target {
174 &mut self.inner
175 }
176}
177
178unsafe impl<T: ?Sized, Token: TokenTrait> Sync for TokenCell<T, Token> {}
179
180impl<T: ?Sized, Token: TokenTrait> TokenCellTrait<T, Token> for TokenCell<T, Token> {
181 fn new(inner: T, token: &Token) -> Self
182 where
183 T: Sized,
184 {
185 TokenCell {
186 inner: UnsafeCell::new(inner),
187 token_id: token.identifier(),
188 }
189 }
190 fn try_guard<'l>(
191 &'l self,
192 token: &'l Token,
193 ) -> Result<TokenGuard<'l, T, Token>, <Token as TokenTrait>::ComparisonError> {
194 token
195 .compare(&self.token_id)
196 .map_likely(move |_| TokenGuard { cell: self, token })
197 }
198 fn try_borrow<'l>(&'l self, token: &'l Token) -> Result<&'l T, Token::ComparisonError> {
199 token
200 .compare(&self.token_id)
201 .map_likely(move |_| unsafe { &*self.inner.get() })
202 }
203 fn try_guard_mut<'l>(
204 &'l self,
205 token: &'l mut Token,
206 ) -> Result<TokenGuardMut<'l, T, Token>, <Token as TokenTrait>::ComparisonError> {
207 token
208 .compare(&self.token_id)
209 .map_likely(move |_| TokenGuardMut { cell: self, token })
210 }
211
212 fn try_borrow_mut<'l>(
213 &'l self,
214 token: &'l mut Token,
215 ) -> Result<&'l mut T, Token::ComparisonError> {
216 token
217 .compare(&self.token_id)
218 .map_likely(move |_| unsafe { &mut *self.inner.get() })
219 }
220}