pub use self::core::MoveCell;
#[allow(unsafe_code)]
mod core {
use std::cell::UnsafeCell;
use std::mem;
pub struct MoveCell<T> {
value: UnsafeCell<T>
}
unsafe impl<T> Send for MoveCell<T> where T: Send {}
impl<T> MoveCell<T> {
#[inline]
pub fn new(value: T) -> Self {
MoveCell {
value: UnsafeCell::new(value)
}
}
pub fn into_inner(self) -> T {
unsafe { self.value.into_inner() }
}
#[inline]
pub fn replace(&self, value: T) -> T {
unsafe {
mem::replace(&mut *self.value.get(), value)
}
}
#[inline]
pub fn as_ptr(&self) -> *mut T {
self.value.get()
}
pub fn as_mut(&mut self) -> &mut T {
unsafe { &mut *self.value.get() }
}
}
}
impl<T: Default> Default for MoveCell<T> {
#[inline]
fn default() -> Self {
MoveCell::new(Default::default())
}
}
impl<T> From<T> for MoveCell<T> {
#[inline]
fn from(value: T) -> Self {
MoveCell::new(value)
}
}
#[cfg(test)]
mod tests {
use MoveCell;
#[test]
fn smoketest() {
let x = MoveCell::new("ribosome");
assert_eq!(x.replace("nucleolus"), "ribosome");
assert_eq!(x.into_inner(), "nucleolus");
}
#[allow(unsafe_code)]
#[test]
fn as_ptr() {
let x = MoveCell::new("ribosome");
let ptr = x.as_ptr();
unsafe { *ptr = "nucleolus"; }
assert_eq!(x.into_inner(), "nucleolus");
}
#[test]
fn as_mut() {
let mut x = MoveCell::new("ribosome");
*x.as_mut() = "nucleolus";
assert_eq!(x.into_inner(), "nucleolus");
}
#[test]
fn default() {
let x = MoveCell::<usize>::default();
assert_eq!(x.into_inner(), 0);
}
#[test]
fn from() {
let x = MoveCell::from("ribosome");
assert_eq!(x.into_inner(), "ribosome");
}
#[test]
fn send() {
fn assert_send<T: Send>() {}
assert_send::<MoveCell<usize>>();
}
}