Jlm
CommandGraph.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
7 
8 #include <deque>
9 #include <functional>
10 
11 namespace jlm::tooling
12 {
13 
18 class EntryCommand final : public Command
19 {
20 public:
21  [[nodiscard]] std::string
22  ToString() const override
23  {
24  return "Entry";
25  }
26 
27  void
28  Run() const override
29  {}
30 };
31 
36 class ExitCommand final : public Command
37 {
38 public:
39  [[nodiscard]] std::string
40  ToString() const override
41  {
42  return "Exit";
43  }
44 
45  void
46  Run() const override
47  {}
48 };
49 
51 {
52  EntryNode_ = &Node::Create(*this, std::make_unique<EntryCommand>());
53  ExitNode_ = &Node::Create(*this, std::make_unique<ExitCommand>());
54 }
55 
56 std::vector<CommandGraph::Node *>
58 {
59  std::vector<CommandGraph::Node *> nodes({ &commandGraph.GetEntryNode() });
60  std::deque<CommandGraph::Node *> to_visit({ &commandGraph.GetEntryNode() });
61  std::unordered_set<CommandGraph::Node *> visited({ &commandGraph.GetEntryNode() });
62 
63  while (!to_visit.empty())
64  {
65  auto node = to_visit.front();
66  to_visit.pop_front();
67 
68  for (auto & edge : node->OutgoingEdges())
69  {
70  if (visited.find(&edge.GetSink()) == visited.end())
71  {
72  to_visit.push_back(&edge.GetSink());
73  visited.insert(&edge.GetSink());
74  nodes.push_back(&edge.GetSink());
75  }
76  }
77  }
78 
79  return nodes;
80 }
81 
82 void
84 {
85  for (auto & node : CommandGraph::SortNodesTopological(*this))
86  node->GetCommand().Run();
87 }
88 
89 CommandGraph::Node::~Node() = default;
90 
91 CommandGraph::Node::Node(const CommandGraph & commandGraph, std::unique_ptr<Command> command)
92  : CommandGraph_(commandGraph),
93  Command_(std::move(command))
94 {}
95 
98 {
99  return { IncomingEdgeConstIterator(IncomingEdges_.begin()),
100  IncomingEdgeConstIterator(IncomingEdges_.end()) };
101 }
102 
105 {
106  return { OutgoingEdgeConstIterator(OutgoingEdges_.begin()),
107  OutgoingEdgeConstIterator(OutgoingEdges_.end()) };
108 }
109 
111 CommandGraph::Node::Create(CommandGraph & commandGraph, std::unique_ptr<Command> command)
112 {
113  std::unique_ptr<Node> node(new Node(commandGraph, std::move(command)));
114  return commandGraph.AddNode(std::move(node));
115 }
116 
117 }
Command graph node incoming edge const iterator.
Command graph node outgoing edge const iterator.
OutgoingEdgeConstRange OutgoingEdges() const
static Node & Create(CommandGraph &commandGraph, std::unique_ptr< Command > command)
IncomingEdgeConstRange IncomingEdges() const
Node(const CommandGraph &commandGraph, std::unique_ptr< Command > command)
static std::vector< CommandGraph::Node * > SortNodesTopological(const CommandGraph &commandGraph)
Node & GetEntryNode() const noexcept
Node & AddNode(std::unique_ptr< Node > node)
Command class.
Definition: Command.hpp:30
std::string ToString() const override
void Run() const override
std::string ToString() const override
void Run() const override