Files
lix/lix/libutil/closure.hh
T
eldritch horrors f06040f5d8 libutil: add computeClosureAsync
Change-Id: I5d9a11a106e9e0d9e49d08d1d04f579ba55255a9
2025-02-23 17:18:48 +00:00

61 lines
1.1 KiB
C++

#pragma once
///@file
#include "lix/libutil/async.hh"
#include "lix/libutil/result.hh"
#include <functional>
#include <kj/async.h>
#include <set>
namespace nix {
template<typename T>
std::set<T> computeClosure(
std::set<T> startElts,
std::function<std::set<T>(const T &)> getEdges
)
{
std::set<T> res, queue = std::move(startElts);
while (!queue.empty()) {
std::set<T> next;
for (auto & e : queue) {
if (res.insert(e).second) {
next.merge(getEdges(e));
}
}
queue = std::move(next);
}
return res;
}
template<typename T>
kj::Promise<Result<std::set<T>>> computeClosureAsync(
std::set<T> startElts,
std::function<kj::Promise<Result<std::set<T>>>(const T &)> getEdges
)
try {
std::set<T> res, queue = std::move(startElts);
while (!queue.empty()) {
std::set<T> next;
for (auto & e : queue) {
if (res.insert(e).second) {
next.merge(LIX_TRY_AWAIT(getEdges(e)));
}
}
queue = std::move(next);
}
co_return res;
} catch (...) {
co_return result::current_exception();
}
}