use core::{cmp::Ordering, fmt};
use smallvec::SmallVec;
use super::SmallDeque;
pub struct SmallPriorityQueue<T, const N: usize = 8> {
pq: SmallDeque<T, N>,
}
impl<T: fmt::Debug, const N: usize> fmt::Debug for SmallPriorityQueue<T, N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}
impl<T, const N: usize> Default for SmallPriorityQueue<T, N> {
fn default() -> Self {
Self {
pq: Default::default(),
}
}
}
impl<T: Clone, const N: usize> Clone for SmallPriorityQueue<T, N> {
fn clone(&self) -> Self {
Self {
pq: self.pq.clone(),
}
}
fn clone_from(&mut self, source: &Self) {
self.pq.clone_from(&source.pq);
}
}
impl<T, const N: usize> SmallPriorityQueue<T, N> {
#[inline]
pub fn is_empty(&self) -> bool {
self.pq.is_empty()
}
#[inline]
pub fn len(&self) -> usize {
self.pq.len()
}
#[inline]
pub fn pop(&mut self) -> Option<T> {
self.pq.pop_front()
}
#[inline]
pub fn pop_last(&mut self) -> Option<T> {
self.pq.pop_back()
}
#[inline]
pub fn front(&self) -> Option<&T> {
self.pq.front()
}
#[inline]
pub fn back(&self) -> Option<&T> {
self.pq.back()
}
#[inline]
pub fn iter(&self) -> super::smalldeque::Iter<'_, T> {
self.pq.iter()
}
}
impl<T, const N: usize> SmallPriorityQueue<T, N>
where
T: Ord,
{
pub const fn new() -> Self {
Self {
pq: SmallDeque::new(),
}
}
pub fn push(&mut self, item: T) {
if let Some(head) = self.pq.front() {
match head.cmp(&item) {
Ordering::Greater => self.push_slow(item),
Ordering::Equal | Ordering::Less => {
self.pq.push_front(item);
}
}
} else {
self.pq.push_back(item);
}
}
fn push_slow(&mut self, item: T) {
match self.pq.binary_search_by(|probe| probe.cmp(&item)) {
Ok(index) => {
self.pq.insert(index, item);
}
Err(index) => {
self.pq.insert(index, item);
}
}
}
}
impl<T, const N: usize> IntoIterator for SmallPriorityQueue<T, N> {
type IntoIter = super::smalldeque::IntoIter<T, N>;
type Item = T;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.pq.into_iter()
}
}
impl<T, const N: usize> FromIterator<T> for SmallPriorityQueue<T, N>
where
T: Ord,
{
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut pq = SmallDeque::from_iter(iter);
let items = pq.make_contiguous();
items.sort();
Self { pq }
}
}
impl<T: Ord, const N: usize> From<SmallVec<[T; N]>> for SmallPriorityQueue<T, N> {
fn from(mut value: SmallVec<[T; N]>) -> Self {
value.sort();
Self {
pq: SmallDeque::from(value),
}
}
}