1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-16 05:51:05 +01:00
nix/src/libutil/include/nix/util/topo-sort.hh
Eelco Dolstra 1507843f6c Cleanup: Use C++23 "explicit this" for recursive lambdas
Try to pass by reference where possible.

Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo>
2025-10-30 15:56:06 -04:00

44 lines
1.1 KiB
C++

#pragma once
///@file
#include "nix/util/error.hh"
namespace nix {
template<typename T, typename Compare>
std::vector<T> topoSort(
std::set<T, Compare> items,
std::function<std::set<T, Compare>(const T &)> getChildren,
std::function<Error(const T &, const T &)> makeCycleError)
{
std::vector<T> sorted;
decltype(items) visited, parents;
auto dfsVisit = [&](this auto & dfsVisit, const T & path, const T * parent) {
if (parents.count(path))
throw makeCycleError(path, *parent);
if (!visited.insert(path).second)
return;
parents.insert(path);
auto references = getChildren(path);
for (auto & i : references)
/* Don't traverse into items that don't exist in our starting set. */
if (i != path && items.count(i))
dfsVisit(i, &path);
sorted.push_back(path);
parents.erase(path);
};
for (auto & i : items)
dfsVisit(i, nullptr);
std::reverse(sorted.begin(), sorted.end());
return sorted;
}
} // namespace nix