use std::mem;
pub trait Set<T> {
fn set_insert(&mut self, t: T) -> bool;
}
impl<T: Ord> Set<T> for Vec<T> {
fn set_insert(&mut self, val: T) -> bool {
self.binary_search(&val)
.map_err(|i| self.insert(i, val))
.is_err()
}
}
pub trait Map<K, V> {
fn map_insert(&mut self, key: K, val: V) -> Option<V>;
fn map_remove(&mut self, key: &K) -> Option<(K, V)>;
fn map_lookup(&self, key: &K) -> Option<&V>;
fn find_gte(&self, key: &K) -> Option<&V>;
}
#[inline]
pub fn first<L, R>(tup: &(L, R)) -> &L {
&tup.0
}
#[inline]
pub fn second<L, R>(tup: &(L, R)) -> &R {
&tup.1
}
impl<K: Ord, V> Map<K, V> for Vec<(K, V)> {
fn map_insert(&mut self, key: K, val: V) -> Option<V> {
match self.binary_search_by_key(&&key, first) {
Err(i) => {
self.insert(i, (key, val));
Err(())
}
Ok(i) => Ok(mem::replace(
&mut unsafe { self.get_unchecked_mut(i) }.1,
val,
)),
}
.ok()
}
fn map_remove(&mut self, key: &K) -> Option<(K, V)> {
self.binary_search_by_key(&key, first)
.map(|i| self.remove(i))
.ok()
}
fn map_lookup(&self, key: &K) -> Option<&V> {
self.binary_search_by_key(&key, first)
.map(|i| unsafe { self.get_unchecked(i) })
.map(second)
.ok()
}
fn find_gte(&self, key: &K) -> Option<&V> {
let checked = |i| match self.len() {
n if n == 0 => None,
n if n == i => Some(0),
_ => Some(i),
};
self.binary_search_by_key(&key, first)
.map_or_else(checked, Some)
.map(|i| unsafe { self.get_unchecked(i) })
.map(second)
}
}
pub struct Prependable<I, T> {
inner: I,
pre: Vec<T>,
}
impl<I: Iterator<Item = T>, T> Iterator for Prependable<I, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.pre.pop().or_else(|| self.inner.next())
}
}
impl<I: Iterator<Item = T>, T> Prependable<I, T> {
pub fn new(inner: I) -> Self {
Self { inner, pre: vec![] }
}
pub fn push_front(&mut self, elt: T) {
self.pre.push(elt);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn vec_set_insert() {
let mut set = Vec::new();
assert!(set.set_insert(0));
assert!(!set.set_insert(0));
assert!(set.set_insert(5));
assert!(!set.set_insert(5));
assert!(set.set_insert(3));
assert!(!set.set_insert(3));
assert_eq!(vec![0, 3, 5], set);
}
#[test]
fn vec_map_insert() {
let mut map = (0..2).map(|x| (x, x)).collect::<Vec<_>>();
assert_eq!(None, map.map_insert(2, 42));
assert_eq!(vec![(0, 0), (1, 1), (2, 42)], map);
assert_eq!(Some(42), map.map_insert(2, 24));
assert_eq!(vec![(0, 0), (1, 1), (2, 24)], map);
}
#[test]
fn vec_map_remove() {
let mut map = (0..2).map(|x| (x, x)).collect::<Vec<_>>();
assert_eq!(None, map.map_remove(&4));
assert_eq!(Some((1, 1)), map.map_remove(&1));
assert_eq!(vec![(0, 0)], map);
}
#[test]
fn vec_map_lookup() {
let map = (0..2).map(|x| (x, x)).collect::<Vec<_>>();
assert_eq!(Some(&1), map.map_lookup(&1));
assert_eq!(None, map.map_lookup(&3));
}
#[test]
fn vec_map_find_gte() {
let mut map = Vec::default();
assert_eq!(None, map.find_gte(&0));
assert_eq!(None, map.map_insert(1, 2));
assert_eq!(None, map.map_insert(2, 3));
assert_eq!(None, map.map_insert(3, 4));
assert_eq!(vec![(1, 2), (2, 3), (3, 4)], map);
assert_eq!(Some(&2), map.find_gte(&0));
assert_eq!(Some(&2), map.find_gte(&1));
assert_eq!(Some(&3), map.find_gte(&2));
assert_eq!(Some(&4), map.find_gte(&3));
assert_eq!(Some(&2), map.find_gte(&4));
}
}