11std::vector<T> topoSort(std::set<T> items,
12 std::function<std::set<T>(
const T &)> getChildren,
13 std::function<Error(
const T &,
const T &)> makeCycleError)
15 std::vector<T> sorted;
16 std::set<T> visited, parents;
18 std::function<void(
const T & path,
const T * parent)> dfsVisit;
20 dfsVisit = [&](
const T & path,
const T * parent) {
21 if (parents.count(path)) {
22 throw makeCycleError(path, *parent);
25 if (!visited.insert(path).second)
return;
28 std::set<T> references = getChildren(path);
30 for (
auto & i : references)
32 if (i != path && items.count(i))
35 sorted.push_back(path);
39 for (
auto & i : items)
42 std::reverse(sorted.begin(), sorted.end());
48kj::Promise<Result<std::vector<T>>> topoSortAsync(std::set<T> items,
49 std::function<kj::Promise<Result<std::set<T>>>(
const T &)> getChildren,
50 std::function<Error(
const T &,
const T &)> makeCycleError)
52 std::vector<T> sorted;
53 std::set<T> visited, parents;
55 std::function<kj::Promise<Result<void>>(
const T & path,
const T * parent)> dfsVisit;
58 dfsVisit = [&](
const T & path,
const T * parent) -> kj::Promise<Result<void>> {
60 if (parents.count(path)) {
62 throw makeCycleError(path, *parent);
65 if (!visited.insert(path).second)
co_return result::success();
68 std::set<T> references = TRY_AWAIT(getChildren(path));
70 for (
auto & i : references)
72 if (i != path && items.count(i))
73 TRY_AWAIT(dfsVisit(i, &path));
75 sorted.push_back(path);
77 co_return result::success();
79 co_return result::current_exception();
83 for (
auto & i : items)
84 TRY_AWAIT(dfsVisit(i,
nullptr));
86 std::reverse(sorted.begin(), sorted.end());
90 co_return result::current_exception();
This file defines two main structs/classes used in nix error handling.