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))
throw makeCycleError(path, *parent);
23 if (!visited.insert(path).second)
return;
26 std::set<T> references = getChildren(path);
28 for (
auto & i : references)
30 if (i != path && items.count(i))
33 sorted.push_back(path);
37 for (
auto & i : items)
40 std::reverse(sorted.begin(), sorted.end());
46kj::Promise<Result<std::vector<T>>> topoSortAsync(std::set<T> items,
47 std::function<kj::Promise<Result<std::set<T>>>(
const T &)> getChildren,
48 std::function<Error(
const T &,
const T &)> makeCycleError)
50 std::vector<T> sorted;
51 std::set<T> visited, parents;
53 std::function<kj::Promise<Result<void>>(
const T & path,
const T * parent)> dfsVisit;
56 dfsVisit = [&](
const T & path,
const T * parent) -> kj::Promise<Result<void>> {
58 if (parents.count(path))
throw makeCycleError(path, *parent);
60 if (!visited.insert(path).second)
co_return result::success();
63 std::set<T> references = TRY_AWAIT(getChildren(path));
65 for (
auto & i : references)
67 if (i != path && items.count(i))
68 TRY_AWAIT(dfsVisit(i, &path));
70 sorted.push_back(path);
72 co_return result::success();
74 co_return result::current_exception();
78 for (
auto & i : items)
79 TRY_AWAIT(dfsVisit(i, nullptr));
81 std::reverse(sorted.begin(), sorted.end());
85 co_return result::current_exception();
This file defines two main structs/classes used in nix error handling.