12 SmallDenseSet<T> dependBy;
13 SmallDenseSet<T> dependOn;
15 DenseMap<T, Data> data;
19 std::vector<T> sorted;
20 std::vector<T> unsorted;
22 [[nodiscard]]
constexpr bool hasCycles()
const {
return !unsorted.empty(); }
24 void clear() { data.clear(); }
26 [[nodiscard]]
bool contains(T
const& node)
const {
return data.contains(node); }
27 [[nodiscard]]
bool contains(T
const& node, T
const& dependency)
const {
28 if (!contains(dependency)) {
31 return data.at(dependency).dependBy.contains(node);
33 bool emplace(T
const& node) {
40 bool erase(T
const& node) {
42 auto& deps = data.at(node);
43 if (deps.dependBy.size() == 0) {
44 for (
auto& dependency : SmallDenseSet<T>{deps.dependOn}) {
45 eraseDependency(node, dependency);
53 bool emplaceDependency(T
const& node, T
const& dependency) {
54 if (dependency != node) {
55 auto& deps = data[dependency];
56 if (!deps.dependBy.contains(node)) {
57 deps.dependBy.emplace(node);
58 data[node].dependOn.emplace(dependency);
64 bool emplaceDependencies(T
const& node, std::vector<T>
const& dependencies) {
65 for (
auto& dependency : dependencies) {
66 if (!emplaceDependency(node, dependency)) {
72 bool eraseDependency(T
const& node, T
const& dependency) {
73 if (dependency != node && data.contains(dependency)) {
74 auto& deps = data.at(dependency);
75 if (deps.dependBy.contains(node)) {
76 deps.dependBy.erase(node);
77 data[node].dependOn.erase(dependency);
83 SmallDenseSet<T> dependentBy(T
const& node)
const {
84 if (!contains(node)) {
87 return data.at(node).dependBy;
89 SmallDenseSet<T> dependentOn(T
const& node)
const {
90 if (!contains(node)) {
93 return data.at(node).dependOn;
95 [[nodiscard]] SortResult sort()
const {
96 std::vector<T> sorted;
97 std::vector<T> unsorted;
99 DenseMap<T, size_t> csize;
100 for (
auto& [node, deps] : data) {
101 csize[node] = deps.dependOn.size();
104 for (
auto& [node, count] : csize) {
106 sorted.push_back(node);
109 for (
size_t i = 0; i < sorted.size(); i++) {
110 for (
auto const& node : data.at(sorted[i]).dependBy) {
111 if (--csize[node] == 0) {
112 sorted.push_back(node);
116 for (
auto& [node, size] : csize) {
118 unsorted.push_back(node);
121 return {sorted, unsorted};