diff --git a/daggy/include/daggy/DAG.hpp b/daggy/include/daggy/DAG.hpp index 75a9272..dfd6a60 100644 --- a/daggy/include/daggy/DAG.hpp +++ b/daggy/include/daggy/DAG.hpp @@ -1,9 +1,11 @@ #pragma once +#include #include #include #include #include +#include namespace daggy { template @@ -20,6 +22,15 @@ namespace daggy { // Returns the path from {from} to {to} std::deque shortest_path(const T & from, const T & to); + // Breadth First Iterator + struct Iterator { + using iterator_category = std::random_access_iterator_tag; + using difference_type = int; + using value_type = T; + using point = T*; + using reference = T&; + }; + private: struct Vertex { // It's a bit redundant to preserve both, but @@ -34,5 +45,4 @@ namespace daggy { }; #include "DAG.impl" - } diff --git a/daggy/include/daggy/DAG.impl b/daggy/include/daggy/DAG.impl index f37d006..d3b96de 100644 --- a/daggy/include/daggy/DAG.impl +++ b/daggy/include/daggy/DAG.impl @@ -33,6 +33,10 @@ void DAG::addEdge(const T & from, const T & to) { auto & src = vertices.at(from); auto & dst = vertices.at(to); + if (shortest_path(to, from).size() > 1) { + throw std::runtime_error("Unable to add edge that would result in a cycle"); + } + // Add the edge src.children.insert(to); dst.parents.insert(from); diff --git a/tests/unit_dag.cpp b/tests/unit_dag.cpp index 493790d..2879b16 100644 --- a/tests/unit_dag.cpp +++ b/tests/unit_dag.cpp @@ -13,12 +13,10 @@ TEST_CASE("DAG Basic Tests", "[dag]") { dag.addEdge(i-1, i); } - dag.addEdge(5, 9); + REQUIRE(dag.shortest_path(0,9).size() == 10); - auto sp = dag.shortest_path(1,9); - std::cout << "Shortest path from 1 to 10: ("; - for (auto k : sp) { - std::cout << k << " -> "; - } - std::cout << std::endl; + dag.addEdge(5, 9); + REQUIRE(dag.shortest_path(0,9).size() == 7); + + REQUIRE_THROWS(dag.addEdge(9, 5)); }