1 //! Cell primitives. 2 3 use core::cell::UnsafeCell; 4 use core::mem; 5 6 /// A move cell. 7 /// 8 /// This allows you to take ownership and replace the internal data with a new value. The 9 /// functionality is similar to the one provided by [RFC #1659](https://github.com/rust-lang/rfcs/pull/1659). 10 // TODO: Use the features provided by the RFC. 11 pub struct MoveCell<T> { 12 /// The inner data. 13 inner: UnsafeCell<T>, 14 } 15 16 impl<T> MoveCell<T> { 17 /// Create a new cell with some inner data. 18 #[inline] 19 pub const fn new(data: T) -> MoveCell<T> { 20 MoveCell { 21 inner: UnsafeCell::new(data), 22 } 23 } 24 25 /// Replace the inner data and return the old. 26 #[inline] 27 pub fn replace(&self, new: T) -> T { 28 mem::replace(unsafe { 29 // LAST AUDIT: 2016-08-21 (Ticki). 30 31 // This is safe due to never aliasing the value, but simply transfering ownership to 32 // the caller. 33 &mut *self.inner.get() 34 }, new) 35 } 36 } 37 38 #[cfg(test)] 39 mod test { 40 use super::*; 41 42 #[test] 43 fn test_cell() { 44 let cell = MoveCell::new(200); 45 assert_eq!(cell.replace(300), 200); 46 assert_eq!(cell.replace(4), 300); 47 } 48 } 49