|
20 | 20 | #include <cassert>
|
21 | 21 | #include <algorithm>
|
22 | 22 | #include <queue>
|
| 23 | +#include <functional> |
23 | 24 |
|
24 | 25 | #include "invariant.h"
|
25 | 26 |
|
@@ -264,8 +265,12 @@ class grapht
|
264 | 265 |
|
265 | 266 | std::list<node_indext> topsort() const;
|
266 | 267 |
|
| 268 | + std::vector<node_indext> get_successors(const node_indext &n) const; |
267 | 269 | void output_dot(std::ostream &out) const;
|
268 | 270 | void output_dot_node(std::ostream &out, node_indext n) const;
|
| 271 | + void for_each_successor( |
| 272 | + const node_indext &n, |
| 273 | + std::function<void(const node_indext &)> f) const; |
269 | 274 |
|
270 | 275 | protected:
|
271 | 276 | class tarjant
|
@@ -668,23 +673,54 @@ std::list<typename grapht<N>::node_indext> grapht<N>::topsort() const
|
668 | 673 | return nodelist;
|
669 | 674 | }
|
670 | 675 |
|
671 |
| -template<class N> |
672 |
| -void grapht<N>::output_dot(std::ostream &out) const |
| 676 | +template <typename node_index_type> |
| 677 | +void output_dot_generic( |
| 678 | + std::ostream &out, |
| 679 | + node_index_type size, |
| 680 | + const std::function< |
| 681 | + void(const node_index_type &, std::function<void(const node_index_type &)>)> |
| 682 | + &for_each_succ) |
673 | 683 | {
|
674 |
| - for(node_indext n=0; n<nodes.size(); n++) |
675 |
| - output_dot_node(out, n); |
| 684 | + for(node_index_type i = 0; i < size; ++i) |
| 685 | + for_each_succ( |
| 686 | + i, [&](const node_index_type &n) { out << i << " -> " << n << '\n'; }); |
676 | 687 | }
|
677 | 688 |
|
678 |
| -template<class N> |
679 |
| -void grapht<N>::output_dot_node(std::ostream &out, node_indext n) const |
| 689 | +template <class N> |
| 690 | +std::vector<typename grapht<N>::node_indext> |
| 691 | +grapht<N>::get_successors(const node_indext &n) const |
680 | 692 | {
|
681 |
| - const nodet &node=nodes[n]; |
| 693 | + std::vector<node_indext> result; |
| 694 | + std::transform( |
| 695 | + nodes[n].out.begin(), |
| 696 | + nodes[n].out.end(), |
| 697 | + std::back_inserter(result), |
| 698 | + [&](const std::pair<node_indext, edget> &edge) { return edge.first; }); |
| 699 | + return result; |
| 700 | +} |
682 | 701 |
|
683 |
| - for(typename edgest::const_iterator |
684 |
| - it=node.out.begin(); |
685 |
| - it!=node.out.end(); |
686 |
| - it++) |
687 |
| - out << n << " -> " << it->first << '\n'; |
| 702 | +template <class N> |
| 703 | +void grapht<N>::for_each_successor( |
| 704 | + const node_indext &n, |
| 705 | + std::function<void(const node_indext &)> f) const |
| 706 | +{ |
| 707 | + std::for_each( |
| 708 | + nodes[n].out.begin(), |
| 709 | + nodes[n].out.end(), |
| 710 | + [&](const std::pair<node_indext, edget> &edge) { f(edge.first); }); |
| 711 | +} |
| 712 | + |
| 713 | +template <class N> |
| 714 | +void grapht<N>::output_dot(std::ostream &out) const |
| 715 | +{ |
| 716 | + output_dot_generic<node_indext>( |
| 717 | + out, |
| 718 | + (node_indext)nodes.size(), |
| 719 | + [&]( |
| 720 | + const node_indext &i, |
| 721 | + const std::function<void(const node_indext &)> &f) { // NOLINT |
| 722 | + for_each_successor(i, f); |
| 723 | + }); |
688 | 724 | }
|
689 | 725 |
|
690 | 726 | #endif // CPROVER_UTIL_GRAPH_H
|
0 commit comments