Skip to content
GraphForeachNode

GraphForeachNode

Description

Iterate over each live node of given graph.

The loop variable is a GraphNode handle carrying the owning graph plus a stable node id. Marking nodes for deletion is allowed during iteration, but structural changes such as adding nodes, adding edges, clearing, or committing changes will invalidate the traversal and abort on the next iteration step.

Scratch-state operations such as GraphNodeVisit, GraphNodeUnvisit, GraphMarkNodeForDeletion, GraphUnmarkNodeForDeletion, GraphMarkEdgeForRemoval, and GraphUnmarkEdgeForRemoval are the intended mutation tools inside traversal-driven analysis or rewrite passes.

Parameters

Name Direction Description
g in,out Graph to iterate over.
node in Name of the GraphNode loop variable.

Success

Loop body runs once per live node; node carries a fresh handle each step.

Failure

Aborts the traversal on a structural mutation (epoch mismatch) or empty graph; on validator failure (corrupted magic) the process aborts.

Usage example (Cross-references)

Usage examples (Cross-references)
        GraphAddEdge(&graph, c, a);
    
        GraphForeachNode(&graph, node) {
            if (GraphNodeData(&graph, node) == 20) {
                GraphMarkNodeForDeletion(node);
        GraphAddEdge(&graph, b, c);
    
        GraphForeachNode(&graph, node) {
            if (GraphNodeGetId(node) == a) {
                GraphNodeForeachNeighbor(node, neighbor) {
    
    static void city_reset_visits(CityGraph *graph) {
        GraphForeachNode(graph, node) {
            GraphNodeUnvisit(node);
        }
    
    static bool test_graph_city_reachability(void) {
        WriteFmt("Testing GraphForeachNode and GraphNodeForeachNeighbor for reachability\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        city_reset_visits(&graph);
        GraphForeachNode(&graph, node) {
            result = result && (GraphNodeVisitCount(node) == 0);
        }
        GraphAddEdge(&graph, c, d);
    
        GraphForeachNode(&graph, node) {
            (void)MapEnsurePtr(&counts, GraphNodeGetId(node), 0);
            GraphNodeForeachNeighbor(node, neighbor) {
    
    static bool test_graph_node_iteration_rejects_structural_mutation_deadend(void) {
        WriteFmt("Testing GraphForeachNode rejects structural mutation (should abort)\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        GraphAddNodeR(&graph, 2);
    
        GraphForeachNode(&graph, node) {
            (void)node;
            (void)GraphAddNodeR(&graph, 3);
Last updated on