#![allow(clippy::needless_doctest_main)]
mod binary_heap;
pub use crate::binary_heap::*;
#[cfg(test)]
mod from_liballoc {
use super::binary_heap::*;
#[test]
fn test_iterator() {
let data = vec![5, 9, 3];
let iterout = [9, 5, 3];
let heap = BinaryHeap::<_, _>::from(data, |k| k.clone());
let mut i = 0;
for el in &heap {
assert_eq!(*el.1, iterout[i]);
i += 1;
}
}
#[test]
fn test_move_iter_size_hint() {
let data = vec![5, 9];
let pq = BinaryHeap::<_, _>::from(data, |k| k.clone());
let mut it = pq.into_iter();
assert_eq!(it.size_hint(), (2, Some(2)));
assert_eq!(it.next(), Some((9, 9)));
assert_eq!(it.size_hint(), (1, Some(1)));
assert_eq!(it.next(), Some((5, 5)));
assert_eq!(it.size_hint(), (0, Some(0)));
assert_eq!(it.next(), None);
}
#[test]
fn test_peek_and_pop() {
let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
let mut sorted = data.clone();
sorted.sort();
let data = data.into_iter().enumerate().map(|(i, v)| (i, v));
let mut heap: BinaryHeap<_, _> = data.collect();
while !heap.is_empty() {
assert_eq!(heap.peek().unwrap(), sorted.last().unwrap());
assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
}
}
#[test]
fn test_peek_mut() {
let data = [2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]
.into_iter()
.enumerate()
.map(|(i, v)| (i, v));
let mut heap: BinaryHeap<_, _> = data.collect();
assert_eq!(heap.peek(), Some(&10));
{
let mut top = heap.peek_mut().unwrap();
*top -= 2;
}
assert_eq!(heap.peek(), Some(&9));
}
#[test]
fn test_peek_mut_pop() {
let data = [2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]
.into_iter()
.enumerate()
.map(|(i, v)| (i, v));
let mut heap: BinaryHeap<_, _> = data.collect();
assert_eq!(heap.peek(), Some(&10));
{
let mut top = heap.peek_mut().unwrap();
*top -= 2;
assert_eq!(PeekMut::pop(top), 8);
}
assert_eq!(heap.peek(), Some(&9));
}
#[test]
fn test_push() {
let mut heap = BinaryHeap::<_, _>::from(vec![2, 4, 9], |k| k.clone());
assert_eq!(heap.len(), 3);
assert!(*heap.peek().unwrap() == 9);
heap.push(11, 11);
assert_eq!(heap.len(), 4);
assert!(*heap.peek().unwrap() == 11);
heap.push(5, 5);
assert_eq!(heap.len(), 5);
assert!(*heap.peek().unwrap() == 11);
heap.push(27, 27);
assert_eq!(heap.len(), 6);
assert!(*heap.peek().unwrap() == 27);
heap.push(3, 3);
assert_eq!(heap.len(), 7);
assert!(*heap.peek().unwrap() == 27);
heap.push(103, 103);
assert_eq!(heap.len(), 8);
assert!(*heap.peek().unwrap() == 103);
}
#[test]
fn test_push_unique() {
let data: Vec<Box<i32>> = [2, 4, 9].iter().map(|v| Box::new(*v)).collect();
let mut heap = BinaryHeap::<i32, Box<i32>>::from(data, |k| **k);
assert_eq!(heap.len(), 3);
assert!(**heap.peek().unwrap() == 9);
heap.push(11, Box::new(11));
assert_eq!(heap.len(), 4);
assert!(**heap.peek().unwrap() == 11);
heap.push(5, Box::new(5));
assert_eq!(heap.len(), 5);
assert!(**heap.peek().unwrap() == 11);
heap.push(27, Box::new(27));
assert_eq!(heap.len(), 6);
assert!(**heap.peek().unwrap() == 27);
heap.push(3, Box::new(3));
assert_eq!(heap.len(), 7);
assert!(**heap.peek().unwrap() == 27);
heap.push(103, Box::new(103));
assert_eq!(heap.len(), 8);
assert!(**heap.peek().unwrap() == 103);
}
#[test]
fn test_empty_pop() {
let mut heap = BinaryHeap::<i32, i32>::new();
assert!(heap.pop().is_none());
}
#[test]
fn test_empty_peek() {
let empty = BinaryHeap::<i32, i32>::new();
assert!(empty.peek().is_none());
}
#[test]
fn test_empty_peek_mut() {
let mut empty = BinaryHeap::<i32, i32>::new();
assert!(empty.peek_mut().is_none());
}
#[allow(dead_code)]
fn assert_covariance() {
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
d
}
}
#[test]
#[cfg(not(target_os = "emscripten"))]
fn panic_safe() {
use std::cmp;
use std::panic::{self, AssertUnwindSafe};
use std::sync::atomic::{AtomicUsize, Ordering};
use rand::{seq::SliceRandom, thread_rng};
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
#[derive(Eq, PartialEq, PartialOrd, Clone, Debug)]
struct PanicOrd<T>(T, bool);
impl<T> Drop for PanicOrd<T> {
fn drop(&mut self) {
DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
}
}
impl<T: Ord> Ord for PanicOrd<T> {
fn cmp(&self, other: &Self) -> cmp::Ordering {
if self.1 || other.1 {
panic!("Panicking comparison");
}
self.0.cmp(&other.0)
}
}
let mut rng = thread_rng();
const DATASZ: usize = 32;
let ntest = if cfg!(miri) { 1 } else { 10 };
let data = (1..=DATASZ).collect::<Vec<_>>();
for _ in 0..ntest {
for i in 1..=DATASZ {
DROP_COUNTER.store(0, Ordering::SeqCst);
let mut panic_ords: Vec<_> = data
.iter()
.filter(|&&x| x != i)
.map(|&x| PanicOrd(x, false))
.collect();
let panic_item = PanicOrd(i, true);
panic_ords.shuffle(&mut rng);
let mut heap = BinaryHeap::<_, _>::from(panic_ords, |p| p.0);
let inner_data: Vec<PanicOrd<usize>>;
{
let thread_result = {
let mut heap_ref = AssertUnwindSafe(&mut heap);
panic::catch_unwind(move || {
heap_ref.push(panic_item.0, panic_item);
})
};
assert!(thread_result.is_err());
let drops = DROP_COUNTER.load(Ordering::SeqCst);
assert!(drops == 0, "Must not drop items. drops={}", drops);
inner_data = heap.clone().into_values().collect();
drop(heap);
}
let drops = DROP_COUNTER.load(Ordering::SeqCst);
assert_eq!(drops, DATASZ);
let mut data_sorted = inner_data.into_iter().map(|p| p.0).collect::<Vec<_>>();
data_sorted.sort();
assert_eq!(data_sorted, data);
}
}
}
}
#[cfg(feature = "serde")]
#[cfg(test)]
mod tests_serde {
use super::binary_heap::*;
use serde_json;
#[test]
fn deserialized_same_small_vec() {
let vec = vec![1, 2, 3];
let heap = BinaryHeap::<_, _>::from(vec, |k| k.clone());
let serialized = serde_json::to_string(&heap).unwrap();
let deserialized: BinaryHeap<i32, i32> = serde_json::from_str(&serialized).unwrap();
let v0: Vec<_> = heap.into_iter().collect();
let v1: Vec<_> = deserialized.into_iter().collect();
assert_eq!(v0, v1);
}
#[test]
fn deserialized_same() {
let vec: Vec<i32> = (0..1000).collect();
let heap = BinaryHeap::<_, _>::from(vec, |k| k.clone());
let serialized = serde_json::to_string(&heap).unwrap();
let deserialized: BinaryHeap<i32, i32> = serde_json::from_str(&serialized).unwrap();
let v0: Vec<_> = heap.into_iter().collect();
let v1: Vec<_> = deserialized.into_iter().collect();
assert_eq!(v0, v1);
}
}