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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
use std::fmt::Debug; #[macro_export] macro_rules! fixed_array { ($name:ident, $len:expr) => { pub struct $name<T: Copy> { data: [::std::cell::Cell<T>; $len], data_len: ::std::cell::Cell<usize> } impl<T: Copy> $name<T> { pub fn new(default_value: T) -> $name<T> { let mut arr: [::std::cell::Cell<T>; $len] = unsafe { ::std::mem::uninitialized() }; for i in 0..$len { unsafe { ::std::ptr::write(&mut arr[i], ::std::cell::Cell::new(default_value)); } } $name { data: arr, data_len: ::std::cell::Cell::new(0) } } pub fn push(&self, v: T) { let len = self.len(); if len >= self.data.len() { panic!(::errors::VMError::from("FixedArray overflow")); } self.data[len].set(v); self.data_len.set(len + 1); } pub fn pop(&self) -> T { let len = self.len(); if len <= 0 { panic!(::errors::VMError::from("FixedArray underflow")); } let v = self.data[len - 1].get(); self.data_len.set(len - 1); v } pub fn top(&self) -> T { let len = self.len(); if len <= 0 { panic!(::errors::VMError::from("FixedArray underflow")); } self.data[len - 1].get() } pub fn len(&self) -> usize { self.data_len.get() } pub fn get(&self, id: usize) -> Option<T> { if id < self.len() { Some(self.data[id].get()) } else { None } } pub fn set(&self, id: usize, v: T) { if id < self.len() { self.data[id].set(v); } else { panic!(format!("Index out of bound {:?}",id)); } } pub fn clear(&self) { self.data_len.set(0); } } } }