cell.rs 1.2 KB

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