You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
2.6 KiB
Rust
113 lines
2.6 KiB
Rust
#![warn(rust_2018_idioms)]
|
|
#![allow(elided_lifetimes_in_paths)]
|
|
|
|
/// A first-in, first-out queue of characters.
|
|
pub struct Queue {
|
|
older: Vec<char>, // older elements, eldest last.
|
|
younger: Vec<char> // younger elements, youngest last.
|
|
}
|
|
|
|
impl Queue {
|
|
/// Push a character onto the back of a queue.
|
|
pub fn push(&mut self, c: char) {
|
|
self.younger.push(c);
|
|
}
|
|
|
|
/// Pop a character off the front of a queue. Return `Some(c)` if there
|
|
/// was a character to pop, or `None` if the queue was empty.
|
|
pub fn pop(&mut self) -> Option<char> {
|
|
if self.older.is_empty() {
|
|
if self.younger.is_empty() {
|
|
return None;
|
|
}
|
|
|
|
// Bring the elements in younger over to older, and put them in
|
|
// the promised order.
|
|
use std::mem::swap;
|
|
swap(&mut self.older, &mut self.younger);
|
|
self.older.reverse();
|
|
}
|
|
|
|
// Now older is guaranteed to have something. Vec's pop method
|
|
// already returns an Option, so we're set.
|
|
self.older.pop()
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_push_pop() {
|
|
let mut q = Queue { older: Vec::new(), younger: Vec::new() };
|
|
|
|
q.push('0');
|
|
q.push('1');
|
|
assert_eq!(q.pop(), Some('0'));
|
|
|
|
q.push('∞');
|
|
assert_eq!(q.pop(), Some('1'));
|
|
assert_eq!(q.pop(), Some('∞'));
|
|
assert_eq!(q.pop(), None);
|
|
|
|
(&mut q).push('0');
|
|
(&mut q).push('1');
|
|
assert_eq!(q.pop(), Some('0'));
|
|
assert_eq!(q.pop(), Some('1'));
|
|
}
|
|
|
|
impl Queue {
|
|
pub fn is_empty(&self) -> bool {
|
|
self.older.is_empty() && self.younger.is_empty()
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_is_empty() {
|
|
let mut q = Queue { older: Vec::new(), younger: Vec::new() };
|
|
|
|
assert!(q.is_empty());
|
|
q.push('☉');
|
|
assert!(!q.is_empty());
|
|
q.pop();
|
|
assert!(q.is_empty());
|
|
}
|
|
|
|
impl Queue {
|
|
pub fn split(self) -> (Vec<char>, Vec<char>) {
|
|
(self.older, self.younger)
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_split() {
|
|
let mut q = Queue { older: Vec::new(), younger: Vec::new() };
|
|
|
|
q.push('P');
|
|
q.push('D');
|
|
assert_eq!(q.pop(), Some('P'));
|
|
q.push('X');
|
|
|
|
let (older, younger) = q.split();
|
|
// q is now uninitialized.
|
|
assert_eq!(older, vec!['D']);
|
|
assert_eq!(younger, vec!['X']);
|
|
}
|
|
|
|
impl Queue {
|
|
pub fn new() -> Queue {
|
|
Queue { older: Vec::new(), younger: Vec::new() }
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_new() {
|
|
let mut q = Queue::new();
|
|
|
|
q.push('*');
|
|
q.push('1');
|
|
assert_eq!(q.pop(), Some('*'));
|
|
|
|
q.push('∞');
|
|
assert_eq!(q.pop(), Some('1'));
|
|
assert_eq!(q.pop(), Some('∞'));
|
|
assert_eq!(q.pop(), None);
|
|
}
|