|
Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
|
Lazily traverse a graph depth-first or breadth-first. More...
#include <graph-traverse-generators.H>
Public Member Functions | |
| Graph_Traverse_Generator (GT &__g, Show_Arc __sa=Show_Arc()) | |
Construct a lazy traverser bound to graph __g with arc filter __sa. | |
| Aleph::Generator< typename GT::Node * > | traverse (typename GT::Node *start) & |
Lazily traverse the graph from start. | |
Private Types | |
| using | State = graph_traverse_generator_detail::Traverse_State |
Static Private Member Functions | |
| static unsigned char | raw (State s) noexcept |
| static bool | seed_arc (typename GT::Arc *a, typename GT::Node *tgt) noexcept |
Prepare arc a (leading to tgt) for frontier expansion, and report whether the caller should enqueue it. | |
Private Attributes | |
| GT & | g_ |
| Show_Arc | sa_ |
Lazily traverse a graph depth-first or breadth-first.
Mirrors Graph_Traverse (see graph-traverse.H): the queue type Q selects the traversal order (DynListStack for DFS, DynListQueue for BFS — see the Graph_Traverse_DFS_Generator/Graph_Traverse_BFS_Generator aliases below), and Itor iterates the arcs incident to a node.
| GT | Graph type (e.g. List_Graph<...>, List_Digraph<...>). |
| Itor | Arc iterator type for a node (e.g. Node_Arc_Iterator<GT>). |
| Q | Queue template: DynListStack for DFS, DynListQueue for BFS. |
| Show_Arc | Arc filter functor; arcs for which it returns false are skipped, exactly as in Graph_Traverse. |
traverse() is neither reentrant nor thread-safe on a shared GT. It mutates the bound graph directly (g_.reset_nodes(), g_.reset_arcs(), and per-node/per-arc set_state() as the coroutine resumes) rather than tracking state of its own, so at most one active traversal may exist on a given graph at a time. Calling traverse() again on the same GT — from another thread, or from the same thread while a previous Generator from this class is still being iterated (not yet exhausted or destroyed) — resets state out from under that other traversal and corrupts both. Callers needing concurrent or overlapping traversals of the same graph must supply their own external synchronization (e.g. serialize full traversals with a mutex), or traverse separate GT instances. Definition at line 133 of file graph-traverse-generators.H.
|
private |
Definition at line 135 of file graph-traverse-generators.H.
|
inline |
Construct a lazy traverser bound to graph __g with arc filter __sa.
Definition at line 163 of file graph-traverse-generators.H.
|
inlinestaticprivatenoexcept |
Definition at line 140 of file graph-traverse-generators.H.
Referenced by Aleph::Graph_Traverse_Generator< GT, Itor, Q, Show_Arc >::seed_arc(), and Aleph::Graph_Traverse_Generator< GT, Itor, Q, Show_Arc >::traverse().
|
inlinestaticprivatenoexcept |
Prepare arc a (leading to tgt) for frontier expansion, and report whether the caller should enqueue it.
Same semantics as Graph_Traverse::seed_arc (graph-traverse.H) — kept as a separate copy rather than shared because the two classes use different state representations (Traverse_State enum here vs. the GT_Unprocessed/GT_Processing/GT_Processed constants there; see the file-level note on why this header defines its own enum).
Definition at line 149 of file graph-traverse-generators.H.
References Aleph::Graph_Traverse_Generator< GT, Itor, Q, Show_Arc >::raw().
Referenced by Aleph::Graph_Traverse_Generator< GT, Itor, Q, Show_Arc >::traverse().
|
inline |
Lazily traverse the graph from start.
| start | Starting node for the traversal. |
GT::Node *, one per visited node, in the order determined by Q (stack ⇒ DFS, queue ⇒ BFS). | std::invalid_argument | if start == nullptr. Like every Aleph::Generator-returning function, the body doesn't run until the first resume (initial_suspend), so this check fires on the first begin()/operator++() of the returned sequence, not on the traverse(start) call itself — catch it around the iteration, not just around the call. |
&-ref-qualified on purpose: traverse() is a member-function coroutine, so its frame keeps a raw this and doesn't touch g_/sa_ until the first resume — well after a temporary Graph_Traverse_Generator would have been destroyed. Graph_Traverse_BFS_Generator<GT,Itor>(g).traverse(start) is therefore a compile error instead of a dangling-this bug: bind the traverser to a named variable first (as every example and test in this codebase already does) and keep it alive for as long as the returned sequence is iterated. GT — see the class-level note. Do not start a new traversal on this graph until the previous one (if any) is exhausted or its Generator destroyed. Definition at line 192 of file graph-traverse-generators.H.
References ah_invalid_argument_if, Aleph::and, Aleph::blossom_maximum_cardinality_matching(), Aleph::count(), Aleph::Graph_Traverse_Generator< GT, Itor, Q, Show_Arc >::g_, GraphCommon< GT, Node, Arc >::get_connected_node(), GraphCommon< GT, Node, Arc >::get_src_node(), GraphCommon< GT, Node, Arc >::get_tgt_node(), Aleph::Graph_Traverse_Generator< GT, Itor, Q, Show_Arc >::raw(), GraphCommon< GT, Node, Arc >::reset_arcs(), GraphCommon< GT, Node, Arc >::reset_nodes(), Aleph::Graph_Traverse_Generator< GT, Itor, Q, Show_Arc >::sa_, Aleph::Graph_Traverse_Generator< GT, Itor, Q, Show_Arc >::seed_arc(), GTNodeCommon< NodeInfo >::set_state(), GTArcCommon< ArcInfo >::set_state(), GTNodeCommon< NodeInfo >::state(), GTArcCommon< ArcInfo >::state(), and GraphCommon< GT, Node, Arc >::vsize().
Referenced by TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().
|
private |
Definition at line 137 of file graph-traverse-generators.H.
Referenced by Aleph::Graph_Traverse_Generator< GT, Itor, Q, Show_Arc >::traverse().
|
private |
Definition at line 138 of file graph-traverse-generators.H.
Referenced by Aleph::Graph_Traverse_Generator< GT, Itor, Q, Show_Arc >::traverse().