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]
11const fn 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;
30 type RunError;
34 type Identifier;
38 type ComparisonError;
40 type Branded<'a>;
42 fn new() -> Result<Self, Self::ConstructionError>;
47 fn with_token<R, F: for<'a> FnOnce(Self::Branded<'a>) -> R>(f: F) -> Result<R, Self::RunError>;
54 fn identifier(&self) -> Self::Identifier;
56 fn compare(&self, id: &Self::Identifier) -> Result<(), Self::ComparisonError>;
61}
62
63pub trait TokenCellTrait<T: ?Sized, Token: TokenTrait>: Sync {
67 fn new(inner: T, token: &Token) -> Self
69 where
70 T: Sized;
71 fn try_guard<'l>(
77 &'l self,
78 token: &'l Token,
79 ) -> Result<TokenGuard<'l, T, Token>, Token::ComparisonError>;
80 fn try_borrow<'l>(&'l self, token: &'l Token) -> Result<&'l T, Token::ComparisonError>;
85 fn try_guard_mut<'l>(
91 &'l self,
92 token: &'l mut Token,
93 ) -> Result<TokenGuardMut<'l, T, Token>, Token::ComparisonError>;
94 fn try_borrow_mut<'l>(
99 &'l self,
100 token: &'l mut Token,
101 ) -> Result<&'l mut T, Token::ComparisonError>;
102 fn borrow<'l>(&'l self, token: &'l Token) -> &'l T
104 where
105 Token::ComparisonError: core::fmt::Debug,
106 {
107 self.try_borrow(token).unwrap()
108 }
109 fn borrow_mut<'l>(&'l self, token: &'l mut Token) -> &'l mut T
111 where
112 Token::ComparisonError: core::fmt::Debug,
113 {
114 self.try_borrow_mut(token).unwrap()
115 }
116 fn map<'a, U, F: FnOnce(TokenGuard<'a, T, Token>) -> U>(
118 &'a self,
119 f: F,
120 ) -> TokenMap<'a, T, U, F, Self, Token> {
121 TokenMap {
122 cell: self,
123 f,
124 marker: core::marker::PhantomData,
125 }
126 }
127 fn map_mut<'a, U, F: FnOnce(TokenGuardMut<'a, T, Token>) -> U>(
129 &'a self,
130 f: F,
131 ) -> TokenMapMut<'a, T, U, F, Self, Token> {
132 TokenMapMut {
133 cell: self,
134 f,
135 marker: core::marker::PhantomData,
136 }
137 }
138}
139
140pub struct TokenGuard<'a, T: ?Sized, Token: TokenTrait> {
142 cell: &'a TokenCell<T, Token>,
143 token: &'a Token,
144}
145impl<'a, T: ?Sized, Token: TokenTrait> TokenGuard<'a, T, Token> {
146 pub const fn token(&self) -> &Token {
148 self.token
149 }
150}
151impl<'a, T: ?Sized, Token: TokenTrait> Deref for TokenGuard<'a, T, Token> {
152 type Target = T;
153 fn deref(&self) -> &Self::Target {
154 unsafe { &*self.cell.inner.get() }
155 }
156}
157
158pub struct TokenGuardMut<'a, T: ?Sized, Token: TokenTrait> {
160 cell: &'a TokenCell<T, Token>,
161 token: &'a mut Token,
162}
163impl<'a, T: ?Sized, Token: TokenTrait> TokenGuardMut<'a, T, Token> {
164 pub const fn token(&self) -> &Token {
166 self.token
167 }
168 #[rustversion::attr(since(1.83), const)]
170 pub fn token_mut(&mut self) -> &mut Token {
171 self.token
172 }
173}
174impl<'a, T: ?Sized, Token: TokenTrait> Deref for TokenGuardMut<'a, T, Token> {
175 type Target = T;
176 fn deref(&self) -> &Self::Target {
177 unsafe { &*self.cell.inner.get() }
178 }
179}
180impl<'a, T, Token: TokenTrait> core::ops::DerefMut for TokenGuardMut<'a, T, Token> {
181 fn deref_mut(&mut self) -> &mut Self::Target {
182 unsafe { &mut *self.cell.inner.get() }
183 }
184}
185
186pub struct TokenCell<T: ?Sized, Token: TokenTrait> {
188 token_id: Token::Identifier,
189 inner: UnsafeCell<T>,
190}
191impl<T: ?Sized, Token: TokenTrait> TokenCell<T, Token> {
192 #[rustversion::attr(since(1.83), const)]
195 pub fn get_mut(&mut self) -> &mut T {
196 self.inner.get_mut()
197 }
198}
199impl<T: Sized, Token: TokenTrait> TokenCell<T, Token> {
200 pub fn into_inner(self) -> T {
204 self.inner.into_inner()
205 }
206}
207impl<T: ?Sized, Token: TokenTrait> Deref for TokenCell<T, Token> {
208 type Target = UnsafeCell<T>;
209 fn deref(&self) -> &Self::Target {
210 &self.inner
211 }
212}
213impl<T: ?Sized, Token: TokenTrait> DerefMut for TokenCell<T, Token> {
214 fn deref_mut(&mut self) -> &mut Self::Target {
215 &mut self.inner
216 }
217}
218
219unsafe impl<T: ?Sized, Token: TokenTrait> Sync for TokenCell<T, Token> {}
220
221impl<T: ?Sized, Token: TokenTrait> TokenCellTrait<T, Token> for TokenCell<T, Token> {
222 fn new(inner: T, token: &Token) -> Self
223 where
224 T: Sized,
225 {
226 TokenCell {
227 inner: UnsafeCell::new(inner),
228 token_id: token.identifier(),
229 }
230 }
231 fn try_guard<'l>(
232 &'l self,
233 token: &'l Token,
234 ) -> Result<TokenGuard<'l, T, Token>, <Token as TokenTrait>::ComparisonError> {
235 token
236 .compare(&self.token_id)
237 .map_likely(move |_| TokenGuard { cell: self, token })
238 }
239 fn try_borrow<'l>(&'l self, token: &'l Token) -> Result<&'l T, Token::ComparisonError> {
240 token
241 .compare(&self.token_id)
242 .map_likely(move |_| unsafe { &*self.inner.get() })
243 }
244 fn try_guard_mut<'l>(
245 &'l self,
246 token: &'l mut Token,
247 ) -> Result<TokenGuardMut<'l, T, Token>, <Token as TokenTrait>::ComparisonError> {
248 token
249 .compare(&self.token_id)
250 .map_likely(move |_| TokenGuardMut { cell: self, token })
251 }
252
253 fn try_borrow_mut<'l>(
254 &'l self,
255 token: &'l mut Token,
256 ) -> Result<&'l mut T, Token::ComparisonError> {
257 token
258 .compare(&self.token_id)
259 .map_likely(move |_| unsafe { &mut *self.inner.get() })
260 }
261}