38 using SourceCodePath =
typename CodeHandler<Base>::SourceCodePath;
40 std::map<Node*, PathNodeEdges<Base> > graph_;
44 inline bool empty()
const {
45 return graph_.empty();
48 inline void connect(
Node& node,
50 connect(graph_[&node], node, argument);
56 CPPADCG_ASSERT_UNKNOWN(argument < node.getArguments().size());
57 CPPADCG_ASSERT_UNKNOWN(node.getArguments()[argument].getOperation() !=
nullptr);
58 CPPADCG_ASSERT_UNKNOWN(&graph_[&node] == &
nodeInfo);
60 nodeInfo.arguments.push_back(argument);
62 auto*
aNode = node.getArguments()[argument].getOperation();
66 inline bool contains(
Node& node)
const {
67 auto it = graph_.find(&node);
68 return it != graph_.end();
72 auto it = graph_.find(&node);
73 if (
it != graph_.end())
80 auto it = graph_.find(&node);
81 if (
it != graph_.end())
87 inline bool erase(
Node& node) {
88 return graph_.erase(&node) > 0;
103 std::vector<SourceCodePath>
paths;
116 paths[0].reserve(20);
118 if (tail->usage.empty()) {
125 if (
paths.size() > 1)
135 auto*
n =
paths[0][0].node;
137 CPPADCG_ASSERT_UNKNOWN(
edges !=
nullptr);
140 n =
edges->usage.begin()->node;
147 CPPADCG_ASSERT_UNKNOWN(
edges !=
nullptr);
148 CPPADCG_ASSERT_UNKNOWN(!
edges->usage.empty());
166 std::vector<SourceCodePath> findPathUpTo(Node& node,
171 CPPADCG_ASSERT_UNKNOWN(
edges !=
nullptr);
173 std::vector<SourceCodePath>
paths;
177 while (!
edges->arguments.empty()) {
178 if (
edges->arguments.size() > 1) {
183 if (
paths.size() == 2) {
194 paths[0].insert(paths[0].begin(), OperationPathNode<Base>(n, a1Index));
197 paths[1].reserve(paths2[0].size() + 1);
198 paths[1].insert(paths[1].begin(), OperationPathNode<Base>(n, a2Index));
199 paths[1].insert(paths[1].begin() + 1, paths2[0].begin(), paths2[0].end());
203 size_t argIndex1 = *edges->arguments.begin();
204 paths[0].push_back(OperationPathNode<Base>(n, argIndex1));
206 n = n->getArguments()[argIndex1].getOperation();
208 CPPADCG_ASSERT_UNKNOWN(edges !=
nullptr);
211 paths[0].push_back(OperationPathNode<Base>(n, -1));
217 void findPathDownThenUp() {
218 for (
const auto& arg0: tail->usage) {
221 paths[0].push_back(OperationPathNode<Base>(&target, -1));
224 size_t argIndex = arg0.argIndex;
226 const PathNodeEdges<Base>* edges = find(*n);
227 CPPADCG_ASSERT_UNKNOWN(edges !=
nullptr);
230 paths[0].push_back(OperationPathNode<Base>(n, argIndex));
232 if(edges->arguments.size() != 1)
235 if(edges->usage.empty())
237 n = edges->usage.begin()->node;
238 argIndex = edges->usage.begin()->argIndex;
241 CPPADCG_ASSERT_UNKNOWN(edges !=
nullptr);
244 CPPADCG_ASSERT_UNKNOWN(!edges->arguments.empty());
251 std::reverse(paths[0].begin(), paths[0].end());
253 if (edges->arguments.size() == 1) {
260 paths[1].reserve(20);
266 auto* n1 = paths[0][1].node;
267 size_t argIndex1 = n->getArguments()[edges->arguments[0]].getOperation() == n1? edges->arguments[1]: edges->arguments[0];
268 paths[1].push_back(OperationPathNode<Base>(n, argIndex1));
270 n = n->getArguments()[argIndex1].getOperation();
273 CPPADCG_ASSERT_UNKNOWN(edges !=
nullptr);
275 while (!edges->arguments.empty()) {
276 argIndex1 = *edges->arguments.begin();
277 paths[1].push_back(OperationPathNode<Base>(n, argIndex1));
279 n = n->getArguments()[argIndex1].getOperation();
281 CPPADCG_ASSERT_UNKNOWN(edges !=
nullptr);
284 paths[1].push_back(OperationPathNode<Base>(n, -1));