Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmComputeComponentGraph.h
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#pragma once
4
5
#include "cmConfigure.h" // IWYU pragma: keep
6
7
#include <cstddef>
8
#include <stack>
9
#include <vector>
10
11
#include "cmGraphAdjacencyList.h"
12
13
/** \class cmComputeComponentGraph
14
 * \brief Analyze a graph to determine strongly connected components.
15
 *
16
 * Convert a directed graph into a directed acyclic graph whose nodes
17
 * correspond to strongly connected components of the original graph.
18
 *
19
 * We use Tarjan's algorithm to enumerate the components efficiently.
20
 * An advantage of this approach is that the components are identified
21
 * in a topologically sorted order.
22
 */
23
class cmComputeComponentGraph
24
{
25
public:
26
  // Represent the graph with an adjacency list.
27
  using NodeList = cmGraphNodeList;
28
  using EdgeList = cmGraphEdgeList;
29
  using Graph = cmGraphAdjacencyList;
30
31
  cmComputeComponentGraph(Graph const& input);
32
  ~cmComputeComponentGraph();
33
34
  /** Run the computation.  */
35
  void Compute();
36
37
  /** Get the adjacency list of the component graph.  */
38
0
  Graph const& GetComponentGraph() const { return this->ComponentGraph; }
39
  EdgeList const& GetComponentGraphEdges(size_t c) const
40
0
  {
41
0
    return this->ComponentGraph[c];
42
0
  }
43
44
  /** Get map from component index to original node indices.  */
45
  std::vector<NodeList> const& GetComponents() const
46
0
  {
47
0
    return this->Components;
48
0
  }
49
0
  NodeList const& GetComponent(size_t c) const { return this->Components[c]; }
50
51
  /** Get map from original node index to component index.  */
52
  std::vector<size_t> const& GetComponentMap() const
53
0
  {
54
0
    return this->TarjanComponents;
55
0
  }
56
57
  static size_t const INVALID_COMPONENT;
58
59
private:
60
  void TransferEdges();
61
62
  Graph const& InputGraph;
63
  Graph ComponentGraph;
64
65
  // Tarjan's algorithm.
66
  struct TarjanEntry
67
  {
68
    size_t Root;
69
    size_t VisitIndex;
70
  };
71
  std::vector<size_t> TarjanVisited;
72
  std::vector<size_t> TarjanComponents;
73
  std::vector<TarjanEntry> TarjanEntries;
74
  std::vector<NodeList> Components;
75
  std::stack<size_t> TarjanStack;
76
  size_t TarjanWalkId;
77
  size_t TarjanIndex;
78
  void Tarjan();
79
  void TarjanVisit(size_t i);
80
81
  // Connected components.
82
};