1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#include <boost/config.hpp>
#include <fstream>
#include <iostream>
#include <string>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
using namespace boost;
namespace std
{
template < typename T >
std::istream &
operator >> (std::istream & in, std::pair < T, T > &p)
{
in >> p.first >> p.second;
return
in;
}
}
typedef adjacency_list <
listS, // Store out-edges of each vertex in a std::list
vecS, // Store vertex set in a std::vector
directedS // The file dependency graph is directed
> file_dep_graph;
typedef graph_traits <file_dep_graph >::vertex_descriptor vertex_t;
typedef graph_traits <file_dep_graph >::edge_descriptor edge_t;
template < typename Visitor > void
dfs_v1(const file_dep_graph & g, vertex_t u, default_color_type * color,
Visitor vis)
{
color[u] = gray_color;
vis.discover_vertex(u, g);
graph_traits < file_dep_graph >::out_edge_iterator ei, ei_end;
for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
if (color[target(*ei, g)] == white_color) {
vis.tree_edge(*ei, g);
dfs_v1(g, target(*ei, g), color, vis);
} else if (color[target(*ei, g)] == gray_color)
vis.back_edge(*ei, g);
else
vis.forward_or_cross_edge(*ei, g);
}
color[u] = black_color;
vis.finish_vertex(u, g);
}
template < typename Visitor > void
generic_dfs_v1(const file_dep_graph & g, Visitor vis)
{
std::vector < default_color_type > color(num_vertices(g), white_color);
graph_traits < file_dep_graph >::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
if (color[*vi] == white_color)
dfs_v1(g, *vi, &color[0], vis);
}
}
struct dfs_visitor_default
{
template < typename V, typename G > void
discover_vertex(V, const G &)
{
}
template < typename E, typename G > void
tree_edge(E, const G &)
{
}
template < typename E, typename G > void
back_edge(E, const G &)
{
}
template < typename E, typename G > void
forward_or_cross_edge(E, const G &)
{
}
template < typename V, typename G > void
finish_vertex(V, const G &)
{
}
};
struct topo_visitor : public dfs_visitor_default
{
topo_visitor(vertex_t * &order) : topo_order(order)
{
}
void
finish_vertex(vertex_t u, const file_dep_graph &)
{
*--topo_order = u;
}
vertex_t*& topo_order;
};
void
topo_sort(const file_dep_graph & g, vertex_t * topo_order)
{
topo_visitor vis(topo_order);
generic_dfs_v1(g, vis);
}
int
main()
{
std::ifstream file_in("makefile-dependencies.dat");
typedef graph_traits<file_dep_graph>::vertices_size_type size_type;
size_type n_vertices;
file_in >> n_vertices; // read in number of vertices
std::istream_iterator < std::pair < size_type,
size_type > >input_begin(file_in), input_end;
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// VC++ can't handle the iterator constructor
file_dep_graph g(n_vertices);
while (input_begin != input_end) {
size_type i, j;
tie(i, j) = *input_begin++;
add_edge(i, j, g);
}
#else
file_dep_graph g(input_begin, input_end, n_vertices);
#endif
std::vector < std::string > name(num_vertices(g));
std::ifstream name_in("makefile-target-names.dat");
graph_traits < file_dep_graph >::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
name_in >> name[*vi];
std::vector < vertex_t > order(num_vertices(g));
topo_sort(g, &order[0] + num_vertices(g));
for (size_type i = 0; i < num_vertices(g); ++i)
std::cout << name[order[i]] << std::endl;
return 0;
}
|