1 # Perform a reverse topological sort on the given LIST. 3 # vtk_topological_sort(my_list "MY_" "_EDGES") 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. 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: 26 # With the invocation of vtk_topological_sort shown above and these 27 # variables, the resulting reverse topological ordering will be b, a, 30 ############################################################################## 31 # Modified from Boost Utilities 33 # Copyright 2010 Kitware, Inc. 34 ############################################################################## 35 # Copyright 2007 Douglas Gregor <doug.gregor@gmail.com> 36 # Copyright 2007 Troy Straszheim 38 # Distributed under the Boost Software License, Version 1.0. 39 ############################################################################## 40 # Boost Software License - Version 1.0 - August 17th, 2003 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: 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. 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 ############################################################################## 66 # Clear the stack and output variable
67 set(VERTICES
"${${LIST}}")
71 # Loop over all of the
vertices, starting the topological sort from
73 foreach(VERTEX IN LISTS VERTICES)
75 # If we haven't already processed this vertex, start a depth-first 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}")
83 # We've now seen this vertex 84 set(
"FOUND_${VERTEX}" TRUE)
86 # While the depth-first search stack is not empty
88 # Remove the vertex and its remaining out-edges from the top 90 list(GET STACK -1 OUT_EDGES)
91 list(REMOVE_AT STACK -1)
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)
98 # While there are still out-edges remaining 100 # Pull off the first outgoing edge 101 list(GET OUT_EDGES 0 TARGET)
102 list(REMOVE_AT OUT_EDGES 0)
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.
109 # We
've now seen this vertex 110 set("FOUND_${TARGET}" TRUE) 112 # Push the remaining edges for the current vertex onto the 114 string(REPLACE ";" " " NEW_ELEMENT 115 "${SOURCE};${OUT_EDGES}") 116 list(APPEND STACK "${NEW_ELEMENT}") 118 # Setup the new source and outgoing edges 119 set(SOURCE "${TARGET}") 121 "${${PREFIX}${SOURCE}${SUFFIX}}") 125 # We have finished all of the outgoing edges for 126 # SOURCE; add it to the resulting list. 127 list(APPEND ${LIST} ${SOURCE}) 132 set("${LIST}" "${${LIST}}" PARENT_SCOPE) boost::graph_traits< vtkGraph *>::vertex_descriptor target(boost::graph_traits< vtkGraph *>::edge_descriptor e, vtkGraph *)
function vtk_topological_sort(LIST, PREFIX, SUFFIX)
std::pair< boost::graph_traits< vtkGraph *>::edge_iterator, boost::graph_traits< vtkGraph *>::edge_iterator > edges(vtkGraph *g)