use std::ptr; pub struct Queue { head: Link, tail: *mut Item, // Raw, C-like pointer. Cannot be guaranteed safe } type Link = Option>>; struct Item { elem: T, next: Link, } pub struct IntoIter(Queue); pub struct Iter<'a, T:'a> { next: Option<&'a Item>, } pub struct IterMut<'a, T: 'a> { next: Option<&'a mut Item>, } impl Queue { pub fn new() -> Self { Queue { head: None, tail: ptr::null_mut() } } pub fn enqueue(&mut self, elem: T) { let mut new_tail = Box::new(Item { elem: elem, next: None, }); let raw_tail: *mut _ = &mut *new_tail; if !self.tail.is_null() { unsafe { (*self.tail).next = Some(new_tail); } } else { self.head = Some(new_tail); } self.tail = raw_tail; } pub fn dequeue(&mut self) -> Option { self.head.take().map(|head| { let head = *head; self.head = head.next; if self.head.is_none() { self.tail = ptr::null_mut(); } head.elem }) } pub fn peek(&self) -> Option<&T> { self.head.as_ref().map(|item| { &item.elem }) } pub fn peek_mut(&mut self) -> Option<&mut T> { self.head.as_mut().map(|item| { &mut item.elem }) } pub fn into_iter(self) -> IntoIter { IntoIter(self) } pub fn iter(&self) -> Iter { Iter { next: self.head.as_ref().map(|item| &**item) } } pub fn iter_mut(&mut self) -> IterMut { IterMut { next: self.head.as_mut().map(|item| &mut **item) } } } impl Drop for Queue { fn drop(&mut self) { let mut cur_link = self.head.take(); while let Some(mut boxed_item) = cur_link { cur_link = boxed_item.next.take(); } } } impl Iterator for IntoIter { type Item = T; fn next(&mut self) -> Option { self.0.dequeue() } } impl<'a, T> Iterator for Iter<'a, T> { type Item = &'a T; fn next(&mut self) -> Option { self.next.map(|item| { self.next = item.next.as_ref().map(|item| &**item); &item.elem }) } } impl<'a, T> Iterator for IterMut<'a, T> { type Item = &'a mut T; fn next(&mut self) -> Option { self.next.take().map(|item| { self.next = item.next.as_mut().map(|item| &mut **item); &mut item.elem }) } }