Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-utils/src/cell.rs
6939 views
1
//! Copy pasted from std::cell::SyncUnsafeCell
2
//! can be removed once the feature stabilizes.
3
use std::cell::UnsafeCell;
4
5
/// [`UnsafeCell`], but [`Sync`].
6
///
7
/// This is just an [`UnsafeCell`], except it implements [`Sync`]
8
/// if `T` implements [`Sync`].
9
///
10
/// [`UnsafeCell`] doesn't implement [`Sync`], to prevent accidental misuse.
11
/// You can use [`SyncUnsafeCell`] instead of [`UnsafeCell`] to allow it to be
12
/// shared between threads, if that's intentional.
13
/// Providing proper synchronization is still the task of the user,
14
/// making this type just as unsafe to use.
15
///
16
/// See [`UnsafeCell`] for details.
17
#[repr(transparent)]
18
pub struct SyncUnsafeCell<T: ?Sized> {
19
value: UnsafeCell<T>,
20
}
21
22
unsafe impl<T: ?Sized + Sync> Sync for SyncUnsafeCell<T> {}
23
24
impl<T> SyncUnsafeCell<T> {
25
/// Constructs a new instance of [`SyncUnsafeCell`] which will wrap the specified value.
26
#[inline]
27
pub fn new(value: T) -> Self {
28
Self {
29
value: UnsafeCell::new(value),
30
}
31
}
32
33
/// Unwraps the value.
34
#[inline]
35
pub fn into_inner(self) -> T {
36
self.value.into_inner()
37
}
38
}
39
40
impl<T: ?Sized> SyncUnsafeCell<T> {
41
/// Gets a mutable pointer to the wrapped value.
42
///
43
/// This can be cast to a pointer of any kind.
44
/// Ensure that the access is unique (no active references, mutable or not)
45
/// when casting to `&mut T`, and ensure that there are no mutations
46
/// or mutable aliases going on when casting to `&T`
47
#[inline]
48
pub fn get(&self) -> *mut T {
49
self.value.get()
50
}
51
52
/// Returns a mutable reference to the underlying data.
53
///
54
/// This call borrows the [`SyncUnsafeCell`] mutably (at compile-time) which
55
/// guarantees that we possess the only reference.
56
#[inline]
57
pub fn get_mut(&mut self) -> &mut T {
58
self.value.get_mut()
59
}
60
61
/// Gets a mutable pointer to the wrapped value.
62
///
63
/// See [`UnsafeCell::get`] for details.
64
#[inline]
65
pub fn raw_get(this: *const Self) -> *mut T {
66
// We can just cast the pointer from `SyncUnsafeCell<T>` to `T` because
67
// of #[repr(transparent)] on both SyncUnsafeCell and UnsafeCell.
68
// See UnsafeCell::raw_get.
69
this as *const T as *mut T
70
}
71
}
72
73
impl<T: Default> Default for SyncUnsafeCell<T> {
74
/// Creates an `SyncUnsafeCell`, with the `Default` value for T.
75
fn default() -> SyncUnsafeCell<T> {
76
SyncUnsafeCell::new(Default::default())
77
}
78
}
79
80
impl<T> From<T> for SyncUnsafeCell<T> {
81
/// Creates a new [`SyncUnsafeCell<T>`] containing the given value.
82
fn from(t: T) -> SyncUnsafeCell<T> {
83
SyncUnsafeCell::new(t)
84
}
85
}
86
87