safe_cell 0.1.0

Safer than std::cell::UnsafeCell!
Documentation
#[derive(Debug, Clone, Default)]
struct SafeCell<T> {
    inner: T,
}

impl<T> SafeCell<T> {
    fn get(&self) -> &T {
        return &self.inner;
    }

    fn get_mut(&mut self) -> &mut T {
        return &mut self.inner;
    }

    fn into_inner(self) -> T {
        return self.inner;
    }

    fn new(value: T) -> Self {
        return SafeCell {
            inner: value,
        };
    }
}

#[cfg(test)]
mod tests {
    use std::thread;
    use std::sync::{Arc, Mutex};
    use super::*;

    #[test]
    fn basic() {
        let mut cell = SafeCell::new(0);
        assert_eq!(cell.get(), &0);
        *cell.get_mut() += 1;
        assert_eq!(cell.get(), &1);

        let mut other_cell = cell.clone();
        *other_cell.get_mut() += 1;
        assert_eq!(other_cell.get(), &2);
        assert_eq!(cell.get(), &1);
        assert_eq!(cell.into_inner(), 1);
    }

    #[test]
    fn share() {
        let cell = Arc::new(Mutex::new(SafeCell::new(0)));
        let copy = cell.clone();

        let lock = cell.lock().unwrap();

        let a = {
            let cell = copy.clone();
            thread::spawn(move || {
                for _ in 0..10 {
                    *cell.lock().unwrap().get_mut() += 1;
                }
            })
        };

        let b = {
            let cell = copy.clone();
            thread::spawn(move || {
                for _ in 0..10 {
                    *cell.lock().unwrap().get_mut() += 2;
                }
            })
        };

        assert_eq!(lock.get(), &0);
        drop(lock);

        a.join().unwrap();
        b.join().unwrap();

        assert_eq!(cell.lock().unwrap().get(), &30);
    }
}