Skip to content

Commit 209a971

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 16f971b commit 209a971

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
@@ -458,6 +458,38 @@ void grapht<N>::visit_reachable(node_indext src)
458458
nodes[index].visited = true;
459459
}
460460

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

0 commit comments

Comments
 (0)