|
| 1 | +//======================================================================= |
| 2 | +// Copyright 2024 |
| 3 | +// Author: Daniel Yang |
| 4 | +// |
| 5 | +// Distributed under the Boost Software License, Version 1.0. (See |
| 6 | +// accompanying file LICENSE_1_0.txt or copy at |
| 7 | +// http://www.boost.org/LICENSE_1_0.txt) |
| 8 | +//======================================================================= |
| 9 | + |
| 10 | +#include <vector> |
| 11 | +#include <string> |
| 12 | + |
| 13 | +#include <boost/config.hpp> |
| 14 | +#include <boost/core/lightweight_test.hpp> |
| 15 | + |
| 16 | +#include <boost/graph/adjacency_list.hpp> |
| 17 | +#include <boost/graph/undirected_dfs.hpp> |
| 18 | + |
| 19 | +using Graph = boost::adjacency_list< |
| 20 | + boost::vecS, |
| 21 | + boost::vecS, |
| 22 | + boost::undirectedS, |
| 23 | + boost::no_property, |
| 24 | + boost::property<boost::edge_color_t, boost::default_color_type>>; |
| 25 | + |
| 26 | +using Vertex = boost::graph_traits<Graph>::vertex_descriptor; |
| 27 | +using Edge = boost::graph_traits<Graph>::edge_descriptor; |
| 28 | + |
| 29 | +struct DFSVisitorLogger : boost::default_dfs_visitor { |
| 30 | + std::vector<std::string> &log; |
| 31 | + |
| 32 | + DFSVisitorLogger(std::vector<std::string> &log) : log(log) {} |
| 33 | + |
| 34 | + void log_vertex(const Vertex v, const std::string &event) { |
| 35 | + log.push_back("vertex " + std::to_string(v) + " " + event); |
| 36 | + } |
| 37 | + void log_edge(const Edge e, const std::string &event, const Graph &g) { |
| 38 | + log.push_back("edge (" + std::to_string(boost::source(e, g)) + "," + std::to_string(boost::target(e, g)) + ") " + event); |
| 39 | + } |
| 40 | + |
| 41 | + void discover_vertex(Vertex v, const Graph &g) { |
| 42 | + log_vertex(v, "discovered"); |
| 43 | + } |
| 44 | + void finish_vertex(Vertex v, const Graph &g) { |
| 45 | + log_vertex(v, "finished"); |
| 46 | + } |
| 47 | + void examine_edge(Edge e, const Graph &g) { |
| 48 | + log_edge(e, "examined", g); |
| 49 | + } |
| 50 | + void tree_edge(Edge e, const Graph &g) { |
| 51 | + log_edge(e, "tree", g); |
| 52 | + } |
| 53 | + void back_edge(Edge e, const Graph &g) { |
| 54 | + log_edge(e, "back", g); |
| 55 | + } |
| 56 | + void forward_or_cross_edge(Edge e, const Graph &g) { |
| 57 | + log_edge(e, "forward_cross", g); |
| 58 | + } |
| 59 | + void finish_edge(Edge e, const Graph &g) { |
| 60 | + log_edge(e, "finished", g); |
| 61 | + } |
| 62 | +}; |
| 63 | + |
| 64 | +int main() { |
| 65 | + Graph g(3); |
| 66 | + boost::add_edge(0, 1, g); |
| 67 | + boost::add_edge(1, 2, g); |
| 68 | + |
| 69 | + std::vector<std::string> expected_answer = { |
| 70 | + "vertex 0 discovered", |
| 71 | + "edge (0,1) examined", |
| 72 | + "edge (0,1) tree", |
| 73 | + "vertex 1 discovered", |
| 74 | + "edge (1,0) examined", |
| 75 | + "edge (1,0) finished", |
| 76 | + "edge (1,2) examined", |
| 77 | + "edge (1,2) tree", |
| 78 | + "vertex 2 discovered", |
| 79 | + "edge (2,1) examined", |
| 80 | + "edge (2,1) finished", |
| 81 | + "vertex 2 finished", |
| 82 | + "edge (1,2) finished", |
| 83 | + "vertex 1 finished", |
| 84 | + "edge (0,1) finished", |
| 85 | + "vertex 0 finished", |
| 86 | + }; |
| 87 | + std::vector<std::string> actual_answer; |
| 88 | + |
| 89 | + // run undirected_dfs |
| 90 | + DFSVisitorLogger dfs_visitor_logger(actual_answer); |
| 91 | + boost::undirected_dfs(g, |
| 92 | + boost::visitor(dfs_visitor_logger) |
| 93 | + .edge_color_map(boost::get(boost::edge_color, g))); |
| 94 | + |
| 95 | + // check if all vertices and edges have been visited in the correct order |
| 96 | + BOOST_TEST(expected_answer.size() == actual_answer.size()); |
| 97 | + if (expected_answer.size() == actual_answer.size()) { |
| 98 | + for (int i = 0; i < expected_answer.size(); ++i) { |
| 99 | + BOOST_TEST(expected_answer[i] == actual_answer[i]); |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + return boost::report_errors(); |
| 104 | +} |
0 commit comments