File: topo-sort-file-dep2.cpp

package info (click to toggle)
boost 1.33.1-10
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 100,948 kB
  • ctags: 145,103
  • sloc: cpp: 573,492; xml: 49,055; python: 15,626; ansic: 13,588; sh: 2,099; yacc: 858; makefile: 660; perl: 427; lex: 111; csh: 6
file content (152 lines) | stat: -rw-r--r-- 4,044 bytes parent folder | download | duplicates (4)
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;
}