Skip to content

Instantly share code, notes, and snippets.

@dinfuehr
Created March 24, 2017 09:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dinfuehr/3f1a387d87b27853323bc70f65cd7b4b to your computer and use it in GitHub Desktop.
Save dinfuehr/3f1a387d87b27853323bc70f65cd7b4b to your computer and use it in GitHub Desktop.
use std::cell::RefCell;
use std::ops::Index;
struct GrowableVec<T> {
elements: RefCell<Vec<Box<RefCell<T>>>>,
}
impl<T> GrowableVec<T> {
fn new() -> GrowableVec<T> {
GrowableVec {
elements: RefCell::new(Vec::new())
}
}
fn push(&self, val: T) {
self.elements.borrow_mut().push(Box::new(RefCell::new(val)));
}
fn len(&self) -> usize {
self.elements.borrow().len()
}
fn iter(&self) -> GrowableVecIter<T> {
GrowableVecIter {
vec: self,
idx: 0,
}
}
}
impl<T> Index<usize> for GrowableVec<T> {
type Output = RefCell<T>;
fn index(&self, idx: usize) -> &RefCell<T> {
let elements = self.elements.borrow();
let ptr = elements[idx].as_ref() as *const _;
unsafe { &*ptr }
}
}
struct GrowableVecIter<'a, T> where T: 'a {
vec: &'a GrowableVec<T>,
idx: usize,
}
impl<'a, T> Iterator for GrowableVecIter<'a, T> {
type Item = &'a RefCell<T>;
fn next(&mut self) -> Option<&'a RefCell<T>> {
let length = self.vec.len();
if self.idx < length {
let idx = self.idx;
self.idx += 1;
Some(&self.vec[idx])
} else {
None
}
}
}
fn main() {
let vec = GrowableVec::<i32>::new();
{
vec.push(1);
vec.push(2);
let mut elem = vec[1].borrow_mut();
println!("elem = {}", *elem);
println!("len = {}", vec.len());
*elem = 10;
vec.push(3);
println!("elem = {}", *elem);
println!("len = {}", vec.len());
}
for (ind, elem) in vec.iter().enumerate() {
println!("vec.elem[{}] = {}", ind, *elem.borrow());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment