#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include #include "Helpers.h" namespace detail { // Contains helper classes for `NodeClassifier`. template class NodeClassifierStorage; template<> class NodeClassifierStorage { protected: std::unordered_set BackwardsEdgeNodes; }; template<> class NodeClassifierStorage : public NodeClassifierStorage { protected: std::unordered_set LongEdgeNodes; }; template<> class NodeClassifierStorage : public NodeClassifierStorage {}; template<> class NodeClassifierStorage : public NodeClassifierStorage {}; } // namespace detail /// It is used to classify the nodes by selecting the right cluster depending /// on its neighbors. This helps to make routes with edges routed across /// multiple "virtual" nodes that require less bends. template class NodeClassifier : public detail::NodeClassifierStorage { using Storage = detail::NodeClassifierStorage; enum Cluster { Left = 0, Middle = 1, Right = 2 }; public: void addBackwardsEdgePartition(NodeView LHS, NodeView RHS) { Storage::BackwardsEdgeNodes.emplace(LHS); Storage::BackwardsEdgeNodes.emplace(RHS); } void addLongEdgePartition(NodeView LHS, NodeView RHS) { if constexpr (RS == RankingStrategy::DepthFirstSearch || RS == RankingStrategy::Topological) { Storage::LongEdgeNodes.emplace(LHS); Storage::LongEdgeNodes.emplace(RHS); } } size_t operator()(NodeView Node) const { if constexpr (RS == RankingStrategy::DepthFirstSearch || RS == RankingStrategy::Topological) if (!Storage::LongEdgeNodes.contains(Node)) return !Storage::BackwardsEdgeNodes.contains(Node) ? Middle : Right; else return Left; else return !Storage::BackwardsEdgeNodes.contains(Node) ? Left : Right; } }; template using MaybeClassifier = std::optional>;