#[cfg(not(feature = "std"))]
use crate::core_iterators::std;
use core::hash::BuildHasher;
use std::cmp::Ord;
#[cfg(feature = "std")]
use std::collections::hash_map::RandomState;
use std::iter::*;
use crate::PriorityQueue;
use super::Index;
#[cfg(feature = "std")]
pub struct ExtractIf<'a, I: 'a, P: 'a, F, H: 'a = RandomState>
where
P: Ord,
{
pq: &'a mut PriorityQueue<I, P, H>,
predicate: F,
idx: Index,
}
#[cfg(not(feature = "std"))]
pub struct ExtractIf<'a, I: 'a, P: 'a, F, H: 'a>
where
P: Ord,
{
pq: &'a mut PriorityQueue<I, P, H>,
predicate: F,
idx: Index,
}
impl<'a, I: 'a, P: 'a, F, H: 'a> ExtractIf<'a, I, P, F, H>
where
P: Ord,
{
pub(crate) fn new(pq: &'a mut PriorityQueue<I, P, H>, predicate: F) -> Self {
ExtractIf {
pq,
predicate,
idx: Index(0),
}
}
}
impl<'a, I: 'a, P: 'a, F, H: 'a> Iterator for ExtractIf<'a, I, P, F, H>
where
P: Ord,
F: FnMut(&mut I, &mut P) -> bool,
H: BuildHasher,
{
type Item = (I, P);
fn next(&mut self) -> Option<Self::Item> {
use indexmap::map::MutableKeys;
loop {
let r: Option<bool> = self
.pq
.store
.map
.get_index_mut2(self.idx.0)
.map(|(i, p)| (self.predicate)(i, p));
match r {
Some(true) => return self.pq.store.swap_remove_index(self.idx),
Some(false) => self.idx.0 += 1,
None => return None,
}
}
}
}
impl<'a, I: 'a, P: 'a, F, H: 'a> Drop for ExtractIf<'a, I, P, F, H>
where
P: Ord,
{
fn drop(&mut self) {
self.pq.heap_build();
}
}
#[cfg(feature = "std")]
pub struct IterMut<'a, I: 'a, P: 'a, H: 'a = RandomState>
where
P: Ord,
{
pq: &'a mut PriorityQueue<I, P, H>,
pos: usize,
}
#[cfg(not(feature = "std"))]
pub struct IterMut<'a, I: 'a, P: 'a, H: 'a>
where
P: Ord,
{
pq: &'a mut PriorityQueue<I, P, H>,
pos: usize,
}
impl<'a, I: 'a, P: 'a, H: 'a> IterMut<'a, I, P, H>
where
P: Ord,
{
pub(crate) fn new(pq: &'a mut PriorityQueue<I, P, H>) -> Self {
IterMut { pq, pos: 0 }
}
}
impl<'a, I: 'a, P: 'a, H: 'a> Iterator for IterMut<'a, I, P, H>
where
P: Ord,
H: BuildHasher,
{
type Item = (&'a mut I, &'a mut P);
fn next(&mut self) -> Option<Self::Item> {
use indexmap::map::MutableKeys;
let r: Option<(&'a mut I, &'a mut P)> = self
.pq
.store
.map
.get_index_mut2(self.pos)
.map(|(i, p)| (i as *mut I, p as *mut P))
.map(|(i, p)| unsafe { (i.as_mut().unwrap(), p.as_mut().unwrap()) });
self.pos += 1;
r
}
}
impl<'a, I: 'a, P: 'a, H: 'a> Drop for IterMut<'a, I, P, H>
where
P: Ord,
{
fn drop(&mut self) {
self.pq.heap_build();
}
}
#[cfg(feature = "std")]
pub struct IntoSortedIter<I, P, H = RandomState> {
pub(crate) pq: PriorityQueue<I, P, H>,
}
#[cfg(not(feature = "std"))]
pub struct IntoSortedIter<I, P, H> {
pub(crate) pq: PriorityQueue<I, P, H>,
}
impl<I, P, H> Iterator for IntoSortedIter<I, P, H>
where
P: Ord,
{
type Item = (I, P);
fn next(&mut self) -> Option<(I, P)> {
self.pq.pop()
}
}