use std::cmp;
pub trait AutoArray<E> {
fn get_auto(&mut self, index: usize, default_value: E) -> E;
fn set_auto(&mut self, index: usize, element: E, default_value: E);
}
impl<E: Copy> AutoArray<E> for Vec<E> {
fn get_auto(&mut self, index: usize, default_value: E) -> E {
if index < self.len() {
self[index]
} else {
fill(self, index, default_value);
default_value
}
}
fn set_auto(&mut self, index: usize, element: E, default_value: E) {
if index < self.len() {
self[index] = element;
} else {
fill(self, index, default_value);
self[index] = element;
}
}
}
fn fill<E: Copy>(v: &mut Vec<E>, index: usize, default_value: E) {
let additional = cmp::max((index * 2) - v.len(), 1);
v.reserve(additional);
for _ in 0..additional {
v.push(default_value);
}
}
#[cfg(test)]
mod tests {
use super::AutoArray;
#[test]
fn test_auto_array() {
let mut a: Vec<i32> = Vec::new();
a.set_auto(0, 100, 200);
assert!(a.len() > 0);
assert_eq!(a[0], 100);
let mut a: Vec<i32> = Vec::new();
assert_eq!(a.get_auto(0, 100), 100);
assert!(a.len() > 0);
assert_eq!(a[0], 100);
let mut a: Vec<i32> = Vec::new();
a.set_auto(3, 3, 300);
assert_eq!(a[3], 3);
assert_eq!(a[0], 300);
assert_eq!(a[2], 300);
assert!(a.len() > 3);
assert_eq!(a.get_auto(100, 400), 400);
assert!(a.len() > 100);
assert_eq!(a[99], 400);
}
}