vtkTopologicalSort.cmake
Go to the documentation of this file.
1 # Perform a reverse topological sort on the given LIST.
2 #
3 # vtk_topological_sort(my_list "MY_" "_EDGES")
4 #
5 # LIST is the name of a variable containing a list of elements to be
6 # sorted in reverse topological order. Each element in the list has a
7 # set of outgoing edges (for example, those other list elements that
8 # it depends on). In the resulting reverse topological ordering
9 # (written back into the variable named LIST), an element will come
10 # later in the list than any of the elements that can be reached by
11 # following its outgoing edges and the outgoing edges of any vertices
12 # they target, recursively. Thus, if the edges represent dependencies
13 # on build targets, for example, the reverse topological ordering is
14 # the order in which one would build those targets.
15 #
16 # For each element E in this list, the edges for E are contained in
17 # the variable named ${PREFIX}${E}${SUFFIX}. If no such variable
18 # exists, then it is assumed that there are no edges. For example, if
19 # my_list contains a, b, and c, one could provide a dependency graph
20 # using the following variables:
21 #
22 # MY_a_EDGES b
23 # MY_b_EDGES
24 # MY_c_EDGES a b
25 #
26 # With the invocation of vtk_topological_sort shown above and these
27 # variables, the resulting reverse topological ordering will be b, a,
28 # c.
29 
30 ##############################################################################
31 # Modified from Boost Utilities
32 #
33 # Copyright 2010 Kitware, Inc.
34 ##############################################################################
35 # Copyright 2007 Douglas Gregor <doug.gregor@gmail.com>
36 # Copyright 2007 Troy Straszheim
37 #
38 # Distributed under the Boost Software License, Version 1.0.
39 ##############################################################################
40 # Boost Software License - Version 1.0 - August 17th, 2003
41 #
42 # Permission is hereby granted, free of charge, to any person or organization
43 # obtaining a copy of the software and accompanying documentation covered by
44 # this license (the "Software") to use, reproduce, display, distribute,
45 # execute, and transmit the Software, and to prepare derivative works of the
46 # Software, and to permit third-parties to whom the Software is furnished to
47 # do so, all subject to the following:
48 #
49 # The copyright notices in the Software and this entire statement, including
50 # the above license grant, this restriction and the following disclaimer,
51 # must be included in all copies of the Software, in whole or in part, and
52 # all derivative works of the Software, unless such copies or derivative
53 # works are solely in the form of machine-executable object code generated by
54 # a source language processor.
55 #
56 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
58 # FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
59 # SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
60 # FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
61 # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
62 # DEALINGS IN THE SOFTWARE.
63 ##############################################################################
64 
65 function(vtk_topological_sort LIST PREFIX SUFFIX)
66  # Clear the stack and output variable
67  set(VERTICES "${${LIST}}")
68  set(STACK)
69  set(${LIST})
70 
71  # Loop over all of the vertices, starting the topological sort from
72  # each one.
73  foreach(VERTEX IN LISTS VERTICES)
74 
75  # If we haven't already processed this vertex, start a depth-first
76  # search from where.
77  if (NOT FOUND_${VERTEX})
78  # Push this vertex onto the stack with all of its outgoing edges
79  string(REPLACE ";" " " NEW_ELEMENT
80  "${VERTEX};${${PREFIX}${VERTEX}${SUFFIX}}")
81  list(APPEND STACK "${NEW_ELEMENT}")
82 
83  # We've now seen this vertex
84  set("FOUND_${VERTEX}" TRUE)
85 
86  # While the depth-first search stack is not empty
87  while(STACK)
88  # Remove the vertex and its remaining out-edges from the top
89  # of the stack
90  list(GET STACK -1 OUT_EDGES)
91  list(REMOVE_AT STACK -1)
92 
93  # Get the source vertex and the list of out-edges
94  separate_arguments(OUT_EDGES)
95  list(GET OUT_EDGES 0 SOURCE)
96  list(REMOVE_AT OUT_EDGES 0)
97 
98  # While there are still out-edges remaining
99  while (OUT_EDGES)
100  # Pull off the first outgoing edge
101  list(GET OUT_EDGES 0 TARGET)
102  list(REMOVE_AT OUT_EDGES 0)
103 
104  if (NOT FOUND_${TARGET})
105  # We have not seen the target before, so we will traverse
106  # its outgoing edges before coming back to our
107  # source. This is the key to the depth-first traversal.
108 
109  # We've now seen this vertex
110  set("FOUND_${TARGET}" TRUE)
111 
112  # Push the remaining edges for the current vertex onto the
113  # stack
114  string(REPLACE ";" " " NEW_ELEMENT
115  "${SOURCE};${OUT_EDGES}")
116  list(APPEND STACK "${NEW_ELEMENT}")
117 
118  # Setup the new source and outgoing edges
119  set(SOURCE "${TARGET}")
120  set(OUT_EDGES
121  "${${PREFIX}${SOURCE}${SUFFIX}}")
122  endif()
123  endwhile ()
124 
125  # We have finished all of the outgoing edges for
126  # SOURCE; add it to the resulting list.
127  list(APPEND ${LIST} ${SOURCE})
128  endwhile()
129  endif ()
130  endforeach()
131 
132  set("${LIST}" "${${LIST}}" PARENT_SCOPE)
133 endfunction()
boost::graph_traits< vtkGraph *>::vertex_descriptor target(boost::graph_traits< vtkGraph *>::edge_descriptor e, vtkGraph *)
vertices
function vtk_topological_sort(LIST, PREFIX, SUFFIX)
source
std::pair< boost::graph_traits< vtkGraph *>::edge_iterator, boost::graph_traits< vtkGraph *>::edge_iterator > edges(vtkGraph *g)
key