diff --git a/daggy/include/daggy/DAG.hpp b/daggy/include/daggy/DAG.hpp index dfd6a60..b78cada 100644 --- a/daggy/include/daggy/DAG.hpp +++ b/daggy/include/daggy/DAG.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace daggy { template @@ -20,7 +21,29 @@ namespace daggy { void dropEdge(const T & src, const T & dst); // Returns the path from {from} to {to} - std::deque shortest_path(const T & from, const T & to); + std::deque shortestPath(const T & from, const T & to); + + // Traversal + + // Traverse all nodes, calling f(id). If f() returns + // false, stop traversing this branch. + // Guarantees to only visit each vertex once. + void traverse(std::function f); + + // Same as traverse, but starts the traversal at + // the given id. + void traverseFrom(T& id, std::function f); + + + // Peek at the next node + T & next() const; + + // Get the next node and mark it visited + T & visit_next(); + + // Clear the visited flag, optionally for downstream + // vertices + void unvisit(T &id, bool cascade = true); // Breadth First Iterator struct Iterator { @@ -32,12 +55,15 @@ namespace daggy { }; private: + + struct Vertex { // It's a bit redundant to preserve both, but // it makes it possible with and against the // directions possible std::unordered_set parents; std::unordered_set children; + bool visited; }; std::unordered_map vertices; diff --git a/daggy/include/daggy/DAG.impl b/daggy/include/daggy/DAG.impl index d3b96de..b348ea1 100644 --- a/daggy/include/daggy/DAG.impl +++ b/daggy/include/daggy/DAG.impl @@ -2,7 +2,7 @@ template void DAG::addVertex(T id) { if (vertices.find(id) != vertices.end()) throw std::runtime_error("Vertex already exists in graph"); - vertices.emplace(id, Vertex{}); + vertices.emplace(id, Vertex{.visited = false}); roots.insert(id); } @@ -43,7 +43,7 @@ void DAG::addEdge(const T & from, const T & to) { } template -std::deque DAG::shortest_path(const T & from, const T & to) { +std::deque DAG::shortestPath(const T & from, const T & to) { std::deque subpath; if (from == to) return {to};