teo_runtime/cell/mod.rs
1use std::cell::UnsafeCell;
2
3pub struct SyncUnsafeCell<T> {
4 value: UnsafeCell<T>,
5}
6
7unsafe impl<T> Sync for SyncUnsafeCell<T> {}
8
9impl<T> SyncUnsafeCell<T> {
10 /// Constructs a new instance of `SyncUnsafeCell` which will wrap the specified value.
11 #[inline]
12 pub const fn new(value: T) -> Self {
13 Self { value: UnsafeCell::new(value) }
14 }
15}
16
17impl<T> SyncUnsafeCell<T> {
18 /// Gets a mutable pointer to the wrapped value.
19 ///
20 /// This can be cast to a pointer of any kind.
21 /// Ensure that the access is unique (no active references, mutable or not)
22 /// when casting to `&mut T`, and ensure that there are no mutations
23 /// or mutable aliases going on when casting to `&T`
24 #[inline]
25 pub const fn get(&self) -> *mut T {
26 self.value.get()
27 }
28
29 /// Gets a mutable pointer to the wrapped value.
30 ///
31 /// See [`UnsafeCell::get`] for details.
32 #[inline]
33 pub const fn raw_get(this: *const Self) -> *mut T {
34 // We can just cast the pointer from `SyncUnsafeCell<T>` to `T` because
35 // of #[repr(transparent)] on both SyncUnsafeCell and UnsafeCell.
36 // See UnsafeCell::raw_get.
37 this as *const T as *mut T
38 }
39}
40
41impl<T: Default> Default for SyncUnsafeCell<T> {
42 /// Creates an `SyncUnsafeCell`, with the `Default` value for T.
43 fn default() -> SyncUnsafeCell<T> {
44 SyncUnsafeCell::new(Default::default())
45 }
46}
47
48impl<T> From<T> for SyncUnsafeCell<T> {
49 /// Creates a new `SyncUnsafeCell<T>` containing the given value.
50 fn from(t: T) -> SyncUnsafeCell<T> {
51 SyncUnsafeCell::new(t)
52 }
53}