#![deny(missing_docs)]
use std::fmt::{self, Debug};
use std::marker::PhantomData;
use std::mem;
mod node;
pub use node::{IntoIter, Iter};
#[derive(Clone)]
pub struct BinomialHeap<T: Ord> {
root: Option<Box<node::Node<T>>>,
len: usize,
}
impl<T: Ord> BinomialHeap<T> {
pub fn new() -> Self {
BinomialHeap { root: None, len: 0 }
}
pub fn is_empty(&self) -> bool {
self.root.is_none()
}
pub fn len(&self) -> usize {
self.len
}
pub fn iter(&self) -> Iter<T> {
node::iter(&self.root, self.len)
}
pub fn peek(&self) -> Option<&T> {
node::peek(&self.root)
}
pub fn push(&mut self, item: T) {
node::push(&mut self.root, item);
self.len += 1;
}
pub fn append(&mut self, other: &mut Self) {
match self.root {
None => mem::swap(self, other),
Some(ref mut root) => {
node::append(root, other.root.take());
self.len += mem::replace(&mut other.len, 0);
}
}
}
pub fn push_pop(&mut self, item: T) -> T {
self.push(item);
self.pop().expect("heap was empty")
}
pub fn replace(&mut self, item: T) -> Option<T> {
let max = self.pop();
self.push(item);
max
}
pub fn pop(&mut self) -> Option<T> {
node::pop(&mut self.root, &mut self.len)
}
pub fn clear(&mut self) {
*self = Self::new();
}
pub fn drain(&mut self) -> Drain<T> {
Drain { iter: mem::replace(self, Self::new()).into_iter(), marker: PhantomData }
}
}
impl<T: Ord + Debug> Debug for BinomialHeap<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list().entries(self).finish()
}
}
impl<T: Ord> Default for BinomialHeap<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Ord> Extend<T> for BinomialHeap<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, items: I) {
for item in items { self.push(item); }
}
}
impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BinomialHeap<T> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, items: I) {
for item in items { self.push(*item); }
}
}
impl<T: Ord> std::iter::FromIterator<T> for BinomialHeap<T> {
fn from_iter<I: IntoIterator<Item = T>>(items: I) -> Self {
let mut heap = Self::new();
heap.extend(items);
heap
}
}
impl<'a, T: 'a + Ord + Copy> std::iter::FromIterator<&'a T> for BinomialHeap<T> {
fn from_iter<I: IntoIterator<Item = &'a T>>(items: I) -> Self {
let mut heap = Self::new();
heap.extend(items);
heap
}
}
impl<T: Ord> IntoIterator for BinomialHeap<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
node::into_iter(self.root, self.len)
}
}
impl<'a, T: Ord> IntoIterator for &'a BinomialHeap<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
pub struct Drain<'a, T: 'a> {
iter: IntoIter<T>,
marker: PhantomData<&'a mut IntoIter<T>>,
}
impl<'a, T: Ord> Iterator for Drain<'a, T> {
type Item = T;
fn next(&mut self) -> Option<T> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, T: Ord> ExactSizeIterator for Drain<'a, T> {
fn len(&self) -> usize {
self.iter.len()
}
}
#[allow(dead_code)]
fn assert_covariance() {
fn heap<'a, T: Ord>(heap: BinomialHeap<&'static T>) -> BinomialHeap<&'a T> {
heap
}
fn into_iter<'a, T: Ord>(iter: IntoIter<&'static T>) -> IntoIter<&'a T> {
iter
}
fn iter<'i, 'a, T: Ord>(iter: Iter<'i, &'static T>) -> Iter<'i, &'a T> {
iter
}
}