GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 95.9% 117 / 0 / 122
Functions: 33.3% 2 / 0 / 6
Branches: 71.9% 110 / 16 / 169

perm_tree.hpp
Line Branch Exec Source
1 #pragma once
2
3 #include <vector>
4 #include <array>
5 #include <cassert>
6
7 11856 class PermTree {
8 // The tree is "left-associative": INCR/DECR nodes are structured as (1 INCR 2) INCR 3...
9 public:
10 enum class NodeType {
11 LEAF,
12 INCR,
13 DECR,
14 FULL,
15 PARTIAL,
16 };
17
18 struct Node {
19 std::array<int, 2> c;
20 NodeType type;
21 int l, r, lo, hi;
22 };
23
24 std::vector<Node> nodes;
25 int root = -1;
26
27 PermTree() {}
28
8/8
✓ Branch 2 → 3 taken 14452513 times.
✓ Branch 2 → 4 taken 3609497 times.
✓ Branch 3 → 4 taken 3672730 times.
✓ Branch 3 → 7 taken 10779783 times.
✓ Branch 8 → 9 taken 1748763 times.
✓ Branch 8 → 13 taken 9031020 times.
✓ Branch 9 → 10 taken 1527012 times.
✓ Branch 9 → 11 taken 221751 times.
18520645 Node& operator [] (int idx) { return nodes[idx]; }
29 const Node& operator [] (int idx) const { return nodes[idx]; }
30
31
2/2
✓ Branch 982 → 51 taken 74725 times.
✓ Branch 982 → 983 taken 5913 times.
80638 int size() const { return int(nodes.size()); }
32
33
3/8
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 12 → 13 taken 5913 times.
✗ Branch 12 → 20 not taken.
✓ Branch 20 → 21 taken 5913 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 2 → 3 taken 30 times.
✗ Branch 2 → 6 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
✗ Branch 9 → 10 not taken.
5973 PermTree(const std::vector<int>& A) : nodes(A.empty() ? 0 : int(A.size())*2-1) {
34
2/6
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 38 taken 5913 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 30 times.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 14 not taken.
5943 if (A.empty()) { root = -1; return; }
35
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 30 times.
5943 int N = int(A.size());
36
2/3
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 46 → 47 taken 5913 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 11 → 12 taken 30 times.
✗ Branch 17 → 18 not taken.
5943 std::vector<int> nxt_earlier(N);
37
2/3
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 50 → 51 taken 5913 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 12 → 13 taken 30 times.
✗ Branch 21 → 22 not taken.
5943 std::vector<int> prv_earlier(N);
38
4/6
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 60 → 53 taken 40319 times.
✓ Branch 60 → 61 taken 5913 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 15 → 14 taken 9031020 times.
✓ Branch 15 → 16 taken 30 times.
✗ Branch 27 → 24 not taken.
✗ Branch 27 → 28 not taken.
9077282 for (int i = 0; i < N; i++) {
39 9071339 nxt_earlier[i] = i+1;
40 9071339 prv_earlier[i] = i-1;
41 }
42
4/6
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 83 → 62 taken 40319 times.
✓ Branch 83 → 84 taken 5913 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 22 → 17 taken 9031020 times.
✓ Branch 22 → 23 taken 30 times.
✗ Branch 39 → 29 not taken.
✗ Branch 39 → 40 not taken.
9077282 for (int i = N-1; i >= 0; i--) {
43
2/2
✓ Branch 17 → 18 taken 8124136 times.
✓ Branch 17 → 19 taken 906884 times.
9071339 int a = A[i];
44
2/2
✓ Branch 17 → 18 taken 8124136 times.
✓ Branch 17 → 19 taken 906884 times.
9071339 int p = prv_earlier[a];
45 9071339 int n = nxt_earlier[a];
46
4/6
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 72 → 73 taken 25148 times.
✓ Branch 72 → 77 taken 15171 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 17 → 18 taken 8124136 times.
✓ Branch 17 → 19 taken 906884 times.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 35 not taken.
9071339 if (p != -1) nxt_earlier[p] = n;
47
4/6
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 77 → 78 taken 25148 times.
✓ Branch 77 → 82 taken 15171 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 19 → 20 taken 7674358 times.
✓ Branch 19 → 21 taken 1356662 times.
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 38 not taken.
9071339 if (n != N) prv_earlier[n] = p;
48 }
49
50 5943 struct cnd_t {
51 int left;
52 int lo;
53 int lo_gap;
54 int hi;
55 int hi_gap;
56 int node;
57 };
58
59
2/3
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 85 → 754 taken 5913 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 23 → 64 taken 30 times.
✗ Branch 40 → 41 not taken.
5943 std::vector<cnd_t> stk; stk.reserve(N);
60
61
4/6
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 754 → 86 taken 40319 times.
✓ Branch 754 → 755 taken 5913 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 64 → 24 taken 9031020 times.
✓ Branch 64 → 65 taken 30 times.
✗ Branch 189 → 42 not taken.
✗ Branch 189 → 190 not taken.
9077282 for (int i = 0; i < N; i++) {
62 9071339 int a = A[i];
63 16311637 while (true) {
64
12/20
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 92 → 93 taken 45058 times.
✓ Branch 92 → 105 taken 5913 times.
✓ Branch 97 → 98 taken 39732 times.
✓ Branch 97 → 103 taken 5326 times.
✓ Branch 102 → 103 taken 5326 times.
✓ Branch 102 → 105 taken 34406 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 25 → 26 taken 12640487 times.
✓ Branch 25 → 29 taken 30 times.
✓ Branch 26 → 27 taken 10835184 times.
✓ Branch 26 → 28 taken 1805303 times.
✓ Branch 27 → 28 taken 1804194 times.
✓ Branch 27 → 29 taken 9030990 times.
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 51 not taken.
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 50 not taken.
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 51 not taken.
✗ Branch 52 → 53 not taken.
✗ Branch 52 → 97 not taken.
12691488 if (!stk.empty() && (a < stk.back().lo_gap || a > stk.back().hi_gap)) {
65 3620149 assert(stk.size() >= 2);
66
4/4
✓ Branch 33 → 34 taken 3382346 times.
✓ Branch 33 → 35 taken 227151 times.
✓ Branch 36 → 37 taken 3382342 times.
✓ Branch 36 → 38 taken 227155 times.
3641453 stk.end()[-2].lo = std::min(stk.end()[-2].lo, stk.back().lo);
67
2/2
✓ Branch 36 → 37 taken 3382342 times.
✓ Branch 36 → 38 taken 227155 times.
3641453 stk.end()[-2].hi = std::max(stk.end()[-2].hi, stk.back().hi);
68
69 3620149 int n = 2 * stk.back().left - 1;
70 3641453 nodes[n].c = {stk.end()[-2].node, stk.end()[-1].node};
71 3620149 nodes[n].type = NodeType::PARTIAL;
72 3630801 nodes[n].l = stk.end()[-2].left;
73 3620149 nodes[n].r = i-1;
74 3630801 nodes[n].lo = stk.end()[-2].lo;
75 3630801 nodes[n].hi = stk.end()[-2].hi;
76
77 3620149 stk.pop_back();
78
79 3620149 stk.back().node = n;
80 } else {
81 break;
82 }
83 3620149 }
84
85
1/2
✓ Branch 29 → 40 taken 9031020 times.
✗ Branch 101 → 102 not taken.
9111658 stk.push_back({i, a, prv_earlier[a]+1, a, nxt_earlier[a]-1, 2*i});
86 9071339 nodes[2*i].type = NodeType::LEAF;
87 9071339 nodes[2*i].c = {-1, -1};
88 9071339 nodes[2*i].l = nodes[2*i].r = i;
89 9071339 nodes[2*i].lo = nodes[2*i].hi = a;
90
91
25/32
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 677 → 678 taken 46424 times.
✓ Branch 677 → 724 taken 17649 times.
✓ Branch 712 → 713 taken 23754 times.
✓ Branch 712 → 714 taken 22670 times.
✓ Branch 724 → 725 taken 46424 times.
✓ Branch 724 → 726 taken 17649 times.
✓ Branch 726 → 727 taken 46424 times.
✓ Branch 726 → 737 taken 17649 times.
✓ Branch 737 → 738 taken 46424 times.
✓ Branch 737 → 739 taken 17649 times.
✓ Branch 739 → 740 taken 46424 times.
✓ Branch 739 → 750 taken 17649 times.
✓ Branch 750 → 751 taken 46424 times.
✓ Branch 750 → 752 taken 17649 times.
✓ Branch 752 → 377 taken 23754 times.
✓ Branch 752 → 753 taken 40319 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✗ Branch 51 → 52 not taken.
✓ Branch 51 → 53 taken 14452513 times.
✓ Branch 53 → 54 taken 12215708 times.
✓ Branch 53 → 61 taken 2236805 times.
✓ Branch 54 → 55 taken 4875561 times.
✓ Branch 54 → 56 taken 7340147 times.
✓ Branch 57 → 58 taken 3055661 times.
✓ Branch 57 → 59 taken 9160047 times.
✓ Branch 60 → 61 taken 6794215 times.
✓ Branch 60 → 62 taken 5421493 times.
✗ Branch 170 → 171 not taken.
✗ Branch 170 → 186 not taken.
✗ Branch 184 → 185 not taken.
✗ Branch 184 → 186 not taken.
✗ Branch 187 → 109 not taken.
✗ Branch 187 → 188 not taken.
14655858 while (stk.size() >= 2 && std::max(stk.back().hi, stk.end()[-2].hi) - std::min(stk.back().lo, stk.end()[-2].lo) == i - stk.end()[-2].left) {
92 // merge these two nodes into one
93
4/4
✓ Branch 42 → 43 taken 2063479 times.
✓ Branch 42 → 44 taken 3358014 times.
✓ Branch 62 → 41 taken 1841728 times.
✓ Branch 62 → 63 taken 3579765 times.
5492755 stk.end()[-2].lo = std::min(stk.end()[-2].lo, stk.back().lo);
94
4/4
✓ Branch 42 → 43 taken 2063479 times.
✓ Branch 42 → 44 taken 3358014 times.
✓ Branch 45 → 46 taken 1841728 times.
✓ Branch 45 → 47 taken 3579765 times.
5492755 stk.end()[-2].hi = std::max(stk.end()[-2].hi, stk.back().hi);
95
96
2/2
✓ Branch 45 → 46 taken 1841728 times.
✓ Branch 45 → 47 taken 3579765 times.
5445247 int n = 2 * stk.back().left - 1;
97
2/2
✓ Branch 45 → 46 taken 1841728 times.
✓ Branch 45 → 47 taken 3579765 times.
5492755 nodes[n].c = {stk.end()[-2].node, stk.end()[-1].node};
98
4/6
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 539 → 540 taken 10073 times.
✓ Branch 539 → 547 taken 13681 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 45 → 46 taken 1841728 times.
✓ Branch 45 → 47 taken 3579765 times.
✗ Branch 139 → 140 not taken.
✗ Branch 139 → 142 not taken.
5492755 if (stk.end()[-2].lo == stk.end()[-1].lo) {
99 1851801 nodes[n].type = NodeType::DECR;
100
4/6
PermTree::PermTree(std::__debug::vector<int, std::allocator<int> > const&):
✓ Branch 581 → 582 taken 10073 times.
✓ Branch 581 → 589 taken 3608 times.
PermTree::PermTree(std::vector<int, std::allocator<int> > const&):
✓ Branch 47 → 48 taken 3358014 times.
✓ Branch 47 → 49 taken 221751 times.
✗ Branch 148 → 149 not taken.
✗ Branch 148 → 151 not taken.
3620808 } else if (stk.end()[-2].hi == stk.end()[-1].hi) {
101 3368087 nodes[n].type = NodeType::INCR;
102 } else {
103 225359 nodes[n].type = NodeType::FULL;
104 }
105 5469001 nodes[n].l = stk.end()[-2].left;
106 5445247 nodes[n].r = i;
107 5469001 nodes[n].lo = stk.end()[-2].lo;
108 5469001 nodes[n].hi = stk.end()[-2].hi;
109
110 5445247 stk.pop_back();
111 5445247 stk.back().node = n;
112 }
113 }
114
115 5943 assert(stk.size() == 1);
116 5943 root = stk.back().node;
117 17769 }
118 };
119