xref: /relibc/ralloc/src/cell.rs (revision 5a42b783d46b59c625e781942fbd5bf048a4ac89)
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