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