1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
use std::cell; #[derive(Debug)] pub struct LazyArray<T>(cell::UnsafeCell<Vec<Option<T>>>); impl<T> LazyArray<T> { pub fn new(size: usize) -> LazyArray<T> { let mut inner = Vec::new(); inner.reserve(size); for _ in 0..size { inner.push(None); } LazyArray(cell::UnsafeCell::new(inner)) } pub fn put(&self, index: usize, t: T) { match &mut unsafe { &mut *self.0.get() }[index] { empty @ &mut None => *empty = Some(t), _ => (), } } pub fn get(&self, index: usize) -> Option<&T> { if let Some(ref element) = unsafe { &*self.0.get() }[index] { Some(element) } else { None } } } #[cfg(test)] mod tests { use super::LazyArray; #[test] fn it_works() { let lazy_array = LazyArray::<i32>::new(10); for i in 0..10 { assert_eq!(lazy_array.get(i), None) } lazy_array.put(7, 112233); for i in 0..10 { assert_eq!(lazy_array.get(i), if i == 7 { Some(&112233) } else { None }) } } #[test] #[should_panic] fn cannot_put_out_of_bounds() { let lazy_array = LazyArray::<i32>::new(10); lazy_array.put(10, 112233); } }