Skip to content

Commit c487c4b

Browse files
Generic get_reachable function
This takes as argument a set and a for_each_successor function. This can be used even by classes that do not inherit from grapht.
1 parent 46d2507 commit c487c4b

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

src/util/graph.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,38 @@ void grapht<N>::visit_reachable(node_indext src)
461461
nodes[index].visited = true;
462462
}
463463

464+
/// Add to `set`, nodes that are reachable from `set`.
465+
///
466+
/// This implements a depth first search using a stack: at each step we pop a
467+
/// node, and push on the stack all its successors that have not yet been
468+
/// visited.
469+
/// \param set: set of source nodes, must be a container with an
470+
/// `insert(const value_type&)` method.
471+
/// \param for_each_successor: function which given a node `n` and a function
472+
/// `f`, applies `f` on all successors of `n`.
473+
template <class Container, typename nodet = typename Container::value_type>
474+
void get_reachable(
475+
Container &set,
476+
const std::function<void(
477+
const typename Container::value_type &,
478+
const std::function<void(const typename Container::value_type &)> &)>
479+
&for_each_successor)
480+
{
481+
std::vector<nodet> stack;
482+
for(const auto &elt : set)
483+
stack.push_back(elt);
484+
485+
while(!stack.empty())
486+
{
487+
auto n = stack.back();
488+
stack.pop_back();
489+
for_each_successor(n, [&](const nodet &node) { // NOLINT
490+
if(set.insert(node).second)
491+
stack.push_back(node);
492+
});
493+
}
494+
}
495+
464496
/// Run depth-first search on the graph, starting from a single source
465497
/// node.
466498
/// \param src The node to start the search from.

0 commit comments

Comments
 (0)