use std::rc::Rc; use std::cell::RefCell; use std::vec::Vec; use std::slice; #[derive(Debug)] enum EntryOrigin { Index(usize), Detached, } impl From for EntryOrigin { fn from(v: usize) -> Self { EntryOrigin::Index(v) } } #[derive(Debug)] pub struct Entry { val: T, index: EntryOrigin, } impl Entry { fn new(val: T, index: usize) -> Entry { Entry { val: val, index: EntryOrigin::Index(index), } } pub fn order(&self) -> Option { match self.index { EntryOrigin::Detached => None, EntryOrigin::Index(idx) => Some(idx), } } } impl ::std::ops::Deref for Entry { type Target = T; fn deref(&self) -> &T { &self.val } } impl ::std::ops::DerefMut for Entry { fn deref_mut(&mut self) -> &mut T { &mut self.val } } pub struct EntryRef(Rc>>); impl Clone for EntryRef { fn clone(&self) -> Self { EntryRef(self.0.clone()) } } impl From> for EntryRef { fn from(v: Entry) -> Self { EntryRef(Rc::new(RefCell::new(v))) } } impl EntryRef { pub fn read(&self) -> ::std::cell::Ref> { self.0.borrow() } pub fn write(&self) -> ::std::cell::RefMut> { self.0.borrow_mut() } pub fn order(&self) -> Option { self.0.borrow().order() } pub fn link_count(&self) -> usize { Rc::strong_count(&self.0) - 1 } } pub struct RefList { items: Vec>, } impl Default for RefList { fn default() -> Self { RefList { items: Default::default() } } } impl RefList { pub fn new() -> Self { Self::default() } pub fn push(&mut self, t: T) -> EntryRef { let idx = self.items.len(); let val: EntryRef<_> = Entry::new(t, idx).into(); self.items.push(val.clone()); val } pub fn begin_delete(&mut self) -> DeleteTransaction { DeleteTransaction { list: self, deleted: Vec::new(), } } pub fn get(&self, idx: usize) -> Option> { self.items.get(idx).cloned() } fn done_delete(&mut self, indices: &[usize]) { for idx in indices { let mut detached = self.items.remove(*idx); detached.write().index = EntryOrigin::Detached; } for index in 0..self.items.len() { let mut next_entry = self.items.get_mut(index).expect("Checked above; qed").write(); let total_less = indices.iter() .take_while(|x| **x < next_entry.order().expect("Items in the list always have order; qed")) .count(); match next_entry.index { EntryOrigin::Detached => unreachable!("Items in the list always have order!"), EntryOrigin::Index(ref mut idx) => { *idx -= total_less; }, }; } } pub fn delete(&mut self, indices: &[usize]) { self.done_delete(indices) } pub fn delete_one(&mut self, index: usize) { self.done_delete(&[index]) } pub fn from_slice(list: &[T]) -> Self where T: Clone { let mut res = Self::new(); for t in list { res.push(t.clone()); } res } pub fn len(&self) -> usize { self.items.len() } pub fn clone_ref(&self, idx: usize) -> EntryRef { self.items[idx].clone() } pub fn get_ref(&self, idx: usize) -> &EntryRef { &self.items[idx] } pub fn iter(&self) -> slice::Iter> { self.items.iter() } } #[must_use] pub struct DeleteTransaction<'a, T> { list: &'a mut RefList, deleted: Vec, } impl<'a, T> DeleteTransaction<'a, T> { pub fn push(self, idx: usize) -> Self { let mut tx = self; tx.deleted.push(idx); tx } pub fn done(self) { let indices = self.deleted; let list = self.list; list.done_delete(&indices[..]); } } #[cfg(test)] mod tests { use super::*; #[test] fn order() { let mut list = RefList::::new(); let item10 = list.push(10); let item20 = list.push(20); let item30 = list.push(30); assert_eq!(item10.order(), Some(0usize)); assert_eq!(item20.order(), Some(1)); assert_eq!(item30.order(), Some(2)); assert_eq!(**item10.read(), 10); assert_eq!(**item20.read(), 20); assert_eq!(**item30.read(), 30); } #[test] fn delete() { let mut list = RefList::::new(); let item10 = list.push(10); let item20 = list.push(20); let item30 = list.push(30); list.begin_delete().push(1).done(); assert_eq!(item10.order(), Some(0)); assert_eq!(item30.order(), Some(1)); assert_eq!(item20.order(), None); } }