1use std::cell::{Cell, OnceCell, RefCell};
6
7use crate::Collect;
8
9pub trait Unlock {
12 type Unlocked: ?Sized;
13
14 unsafe fn unlock_unchecked(&self) -> &Self::Unlocked;
17}
18
19#[derive(Default)]
20#[repr(transparent)]
21pub struct LockedCell<T: ?Sized>(Cell<T>);
22
23impl<T> LockedCell<T> {
24 pub const fn new(value: T) -> LockedCell<T> {
25 LockedCell(Cell::new(value))
26 }
27
28 pub fn into_inner(self) -> T {
29 self.0.into_inner()
30 }
31}
32
33impl<T: Copy> LockedCell<T> {
34 pub fn get(&self) -> T {
35 self.0.get()
36 }
37
38 pub fn get_mut(&mut self) -> &mut T {
39 self.0.get_mut()
40 }
41}
42
43impl<T: ?Sized> LockedCell<T> {
44 pub const fn as_ptr(&self) -> *mut T {
45 self.0.as_ptr()
46 }
47}
48
49impl<T> Clone for LockedCell<T>
50where
51 T: Copy,
52{
53 fn clone(&self) -> Self {
54 Self(self.0.clone())
55 }
56}
57
58impl<T> std::fmt::Debug for LockedCell<T>
59where
60 T: std::fmt::Debug + Copy,
61{
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 f.debug_tuple("LockedCell").field(&self.get()).finish()
64 }
65}
66
67impl<T> From<T> for LockedCell<T> {
68 fn from(value: T) -> Self {
69 LockedCell(Cell::from(value))
70 }
71}
72
73impl<T> PartialEq for LockedCell<T>
74where
75 T: PartialEq + Copy,
76{
77 fn eq(&self, other: &Self) -> bool {
78 self.get() == other.get()
79 }
80}
81
82impl<T> Eq for LockedCell<T> where T: Eq + Copy {}
83
84impl<T> PartialOrd for LockedCell<T>
85where
86 T: PartialOrd + Copy,
87{
88 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
89 self.get().partial_cmp(&other.get())
90 }
91}
92
93impl<T> Ord for LockedCell<T>
94where
95 T: Ord + Copy,
96{
97 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
98 self.get().cmp(&other.get())
99 }
100}
101
102impl<T: ?Sized> Unlock for LockedCell<T> {
103 type Unlocked = core::cell::Cell<T>;
104
105 unsafe fn unlock_unchecked(&self) -> &Self::Unlocked {
106 &self.0
107 }
108}
109
110unsafe impl<T: Copy + Collect> Collect for LockedCell<T> {
111 const NEEDS_TRACE: bool = T::NEEDS_TRACE;
112
113 fn trace(&self, c: &crate::Collector) {
114 self.get().trace(c)
115 }
116}
117
118#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
119#[repr(transparent)]
120pub struct LockedRefCell<T: ?Sized>(core::cell::RefCell<T>);
121
122impl<T> LockedRefCell<T> {
123 pub const fn new(value: T) -> LockedRefCell<T> {
124 Self(RefCell::new(value))
125 }
126
127 pub fn into_inner(self) -> T {
128 self.0.into_inner()
129 }
130}
131
132impl<T> LockedRefCell<T>
133where
134 T: ?Sized,
135{
136 pub fn borrow(&self) -> core::cell::Ref<'_, T> {
137 self.0.borrow()
138 }
139
140 pub fn try_borrow(&self) -> Result<core::cell::Ref<'_, T>, core::cell::BorrowError> {
141 self.0.try_borrow()
142 }
143
144 pub fn as_ptr(&self) -> *mut T {
145 self.0.as_ptr()
146 }
147
148 pub fn get_mut(&mut self) -> &mut T {
149 self.0.get_mut()
150 }
151}
152
153impl<T: ?Sized> Unlock for LockedRefCell<T> {
154 type Unlocked = core::cell::RefCell<T>;
155
156 unsafe fn unlock_unchecked(&self) -> &Self::Unlocked {
157 &self.0
158 }
159}
160
161unsafe impl<T: ?Sized + Collect> Collect for LockedRefCell<T> {
162 const NEEDS_TRACE: bool = T::NEEDS_TRACE;
163
164 fn trace(&self, c: &crate::Collector) {
165 self.borrow().trace(c);
166 }
167}
168
169#[derive(Debug, Default, Clone, PartialEq, Eq)]
170#[repr(transparent)]
171pub struct LockedOnceCell<T>(core::cell::OnceCell<T>);
172
173impl<T> LockedOnceCell<T> {
174 pub const fn new() -> LockedOnceCell<T> {
175 LockedOnceCell(OnceCell::new())
176 }
177
178 pub fn get(&self) -> Option<&T> {
179 self.0.get()
180 }
181
182 pub fn get_mut(&mut self) -> Option<&mut T> {
183 self.0.get_mut()
184 }
185
186 pub fn into_inner(self) -> Option<T> {
187 self.0.into_inner()
188 }
189
190 pub fn take(&mut self) -> Option<T> {
191 self.0.take()
192 }
193}
194
195impl<T> Unlock for LockedOnceCell<T> {
196 type Unlocked = core::cell::OnceCell<T>;
197
198 unsafe fn unlock_unchecked(&self) -> &Self::Unlocked {
199 &self.0
200 }
201}
202
203unsafe impl<T: Collect> Collect for LockedOnceCell<T> {
204 const NEEDS_TRACE: bool = T::NEEDS_TRACE;
205
206 fn trace(&self, c: &crate::Collector) {
207 self.get().trace(c);
208 }
209}