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