use alloc::collections::BTreeSet;
use core::iter::FusedIterator;
#[cfg(feature = "std")]
use std::collections::HashSet;
use oxgraph_topology::{ElementId, ElementPredecessors, ElementSuccessors, TopologyId};
use crate::bfs::core::{Bfs, Forward, GenericState, Reverse, VisitedSet};
type BTreeBfs<'graph, G, D> = Bfs<'graph, G, GenericState<G, BTreeSet<ElementId<G>>>, D>;
#[cfg(feature = "std")]
type HashBfs<'graph, G, D> = Bfs<'graph, G, GenericState<G, HashSet<ElementId<G>>>, D>;
impl<T> VisitedSet<T> for BTreeSet<T>
where
T: TopologyId,
{
fn insert(&mut self, value: T) -> bool {
Self::insert(self, value)
}
}
#[cfg(feature = "std")]
impl<T> VisitedSet<T> for HashSet<T>
where
T: TopologyId,
{
fn insert(&mut self, value: T) -> bool {
Self::insert(self, value)
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct GenericBreadthFirstSearch<'graph, G>
where
G: ElementSuccessors,
{
inner: BTreeBfs<'graph, G, Forward>,
}
impl<G> Iterator for GenericBreadthFirstSearch<'_, G>
where
G: ElementSuccessors,
{
type Item = ElementId<G>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<G> FusedIterator for GenericBreadthFirstSearch<'_, G> where G: ElementSuccessors {}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct GenericReverseBreadthFirstSearch<'graph, G>
where
G: ElementPredecessors,
{
inner: BTreeBfs<'graph, G, Reverse>,
}
impl<G> Iterator for GenericReverseBreadthFirstSearch<'_, G>
where
G: ElementPredecessors,
{
type Item = ElementId<G>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<G> FusedIterator for GenericReverseBreadthFirstSearch<'_, G> where G: ElementPredecessors {}
#[cfg(feature = "std")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct HashBreadthFirstSearch<'graph, G>
where
G: ElementSuccessors,
{
inner: HashBfs<'graph, G, Forward>,
}
#[cfg(feature = "std")]
impl<G> Iterator for HashBreadthFirstSearch<'_, G>
where
G: ElementSuccessors,
{
type Item = ElementId<G>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
#[cfg(feature = "std")]
impl<G> FusedIterator for HashBreadthFirstSearch<'_, G> where G: ElementSuccessors {}
#[cfg(feature = "std")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct HashReverseBreadthFirstSearch<'graph, G>
where
G: ElementPredecessors,
{
inner: HashBfs<'graph, G, Reverse>,
}
#[cfg(feature = "std")]
impl<G> Iterator for HashReverseBreadthFirstSearch<'_, G>
where
G: ElementPredecessors,
{
type Item = ElementId<G>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
#[cfg(feature = "std")]
impl<G> FusedIterator for HashReverseBreadthFirstSearch<'_, G> where G: ElementPredecessors {}
pub fn breadth_first_search_generic<G>(
graph: &G,
start: ElementId<G>,
) -> GenericBreadthFirstSearch<'_, G>
where
G: ElementSuccessors,
{
GenericBreadthFirstSearch {
inner: Bfs::new(graph, GenericState::new(start)),
}
}
pub fn reverse_breadth_first_search_generic<G>(
graph: &G,
start: ElementId<G>,
) -> GenericReverseBreadthFirstSearch<'_, G>
where
G: ElementPredecessors,
{
GenericReverseBreadthFirstSearch {
inner: Bfs::new(graph, GenericState::new(start)),
}
}
#[cfg(feature = "std")]
pub fn breadth_first_search_generic_hash<G>(
graph: &G,
start: ElementId<G>,
) -> HashBreadthFirstSearch<'_, G>
where
G: ElementSuccessors,
{
HashBreadthFirstSearch {
inner: Bfs::new(graph, GenericState::new(start)),
}
}
#[cfg(feature = "std")]
pub fn reverse_breadth_first_search_generic_hash<G>(
graph: &G,
start: ElementId<G>,
) -> HashReverseBreadthFirstSearch<'_, G>
where
G: ElementPredecessors,
{
HashReverseBreadthFirstSearch {
inner: Bfs::new(graph, GenericState::new(start)),
}
}