libpitust 0.1.2

libpitust implements random utility functions I tend to use a lot
Documentation
//! Module `inverted` allows you to create a inverted view of a graph and
//! compute a predecessor set for a graph.

use crate::graph::{GraphBase, GraphPred, GraphRooted, GraphSucc, node_map::NodeMap};

pub struct ComputedPred<G: GraphBase> {
    pred: NodeMap<G, Vec<G::Node>>,
}
impl<G: GraphSucc> ComputedPred<G> {
    #[inline(always)]
    pub fn new(graph: G) -> ComputedPred<G> {
        let mut gp = ComputedPred {
            pred: NodeMap::new(graph),
        };
        gp.do_update(graph);
        gp
    }

    fn do_update(&mut self, graph: G) {
        for node in graph.nodes() {
            for succ in graph.succ_of(node) {
                self.pred[succ].push(node);
            }
        }
    }
    #[inline(always)]
    pub fn update(&mut self, graph: G) {
        self.pred.clear(graph);
        self.do_update(graph);
    }
}

pub struct WithPred<'a, G: GraphBase>(pub G, pub &'a ComputedPred<G>);
impl<'a, G: GraphBase> Clone for WithPred<'a, G> {
    #[inline(always)]
    fn clone(&self) -> Self {
        *self
    }
}
impl<'a, G: GraphBase> Copy for WithPred<'a, G> {}
impl<'a, G: GraphBase> GraphBase for WithPred<'a, G> {
    type Node = G::Node;
    type NodeMapImpl<Value> = G::NodeMapImpl<Value>;

    #[inline(always)]
    fn clear_nodemap<Value>(
        self,
        map: &mut Self::NodeMapImpl<Value>,
        init: impl FnMut(Self::Node) -> Value,
    ) {
        self.0.clear_nodemap(map, init);
    }

    #[inline(always)]
    fn nodes(self) -> impl Iterator<Item = Self::Node> {
        self.0.nodes()
    }
}
impl<'a, G: GraphSucc> GraphSucc for WithPred<'a, G> {
    #[inline(always)]
    fn succ_of(self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
        self.0.succ_of(node)
    }
}
impl<'a, G: GraphBase> GraphPred for WithPred<'a, G> {
    #[inline(always)]
    fn pred_of(self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
        self.1.pred[node].iter().copied()
    }
}
impl<'a, G: GraphRooted> GraphRooted for WithPred<'a, G> {
    type RootInfo = G::RootInfo;

    #[inline(always)]
    fn root_node_from_info(info: Self::RootInfo) -> Self::Node {
        G::root_node_from_info(info)
    }
    #[inline(always)]
    fn root_node_info(self) -> Self::RootInfo {
        G::root_node_info(self.0)
    }
}

pub struct Inverted<G: GraphBase>(pub G);
impl<G: GraphBase> Clone for Inverted<G> {
    fn clone(&self) -> Self {
        *self
    }
}
impl<G: GraphBase> Copy for Inverted<G> {}

impl<G: GraphBase> GraphBase for Inverted<G> {
    type Node = G::Node;
    type NodeMapImpl<Value> = G::NodeMapImpl<Value>;

    fn clear_nodemap<Value>(
        self,
        map: &mut Self::NodeMapImpl<Value>,
        init: impl FnMut(Self::Node) -> Value,
    ) {
        self.0.clear_nodemap(map, init);
    }

    fn nodes(self) -> impl Iterator<Item = Self::Node> {
        self.0.nodes()
    }
}
impl<G: GraphSucc> GraphPred for Inverted<G> {
    #[inline(always)]
    fn pred_of(self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
        self.0.succ_of(node)
    }
}
impl<G: GraphPred> GraphSucc for Inverted<G> {
    #[inline(always)]
    fn succ_of(self, node: Self::Node) -> impl Iterator<Item = Self::Node> {
        self.0.pred_of(node)
    }
}
impl<G: GraphRooted> GraphRooted for Inverted<G> {
    type RootInfo = G::RootInfo;

    #[inline(always)]
    fn root_node_from_info(info: Self::RootInfo) -> Self::Node {
        G::root_node_from_info(info)
    }
    #[inline(always)]
    fn root_node_info(self) -> Self::RootInfo {
        self.0.root_node_info()
    }
}