GCC Code Coverage Report


Directory: ./
File: TestPointerVector.cpp
Date: 2026-03-21 20:51:59
Exec Total Coverage
Lines: 79 79 100.0%
Functions: 22 22 100.0%
Branches: 98 260 37.7%

Line Branch Exec Source
1 #include "PointerVector.hpp"
2
3 #include "Verbose.hpp"
4 #include "compat/gsl14.hpp"
5
6 #include <gmock/gmock.h>
7
8 using namespace testing;
9 using namespace testing::internal;
10
11 // Anonymous namespace for definitions that are local to this file.
12 namespace {
13 // Print the elements of a PointerVector.
14 5 void print(const RawPointerVector<Verbose<>>& container) {
15
6/10
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 14 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 19 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 14 times.
✓ Branch 18 taken 5 times.
33 for (const auto& elem : container) {
16
4/8
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 14 times.
✗ Branch 10 not taken.
✓ Branch 15 taken 14 times.
✗ Branch 16 not taken.
14 std::cout << gsl::czstring{__func__} << ": " << elem << std::endl;
17 14 const auto& name = elem.name();
18
5/16
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 14 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 14 times.
✗ Branch 15 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 14 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
14 EXPECT_THAT(name, Not(HasSubstr("copy")));
19
5/16
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 14 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 14 times.
✗ Branch 15 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 14 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
14 EXPECT_THAT(name, Not(HasSubstr("move")));
20 5 }
21 5 }
22
23 #if __cplusplus >= 202002L // since C++20
24
25 using std::erase_if;
26
27 #else // until C++20
28
29 // [Erase-remove idiom](https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom)
30 template <typename V, typename Predicate>
31 typename V::iterator erase_if(V& v, Predicate p) {
32 return v.erase(std::remove_if(v.begin(), v.end(), p), v.end());
33 }
34
35 #endif // C++20
36
37 } // anonymous namespace
38
39 8 TEST(SharedPointerVector, emplace_back) {
40 // Place elements into container as pointers.
41 2 auto container = SharedPointerVector<Verbose<>>{};
42 2 auto& base = container.base;
43
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("one"));
44
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("two"));
45
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("three"));
46
47
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 print(reference(container));
48 4 }
49
50 8 TEST(SharedPointerVector, push_back) {
51 // Place elements into container as pointers.
52 2 auto container = SharedPointerVector<Verbose<>>{};
53 2 auto& base = container.base;
54
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.push_back(std::make_shared<Verbose<>>("one"));
55
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.push_back(std::make_shared<Verbose<>>("two"));
56
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.push_back(std::make_shared<Verbose<>>("three"));
57
58
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 print(reference(container));
59 4 }
60
61 8 TEST(SharedPointerVector, shallow_copy) {
62 // Place elements into container as pointers.
63 2 auto container = SharedPointerVector<Verbose<>>{};
64 2 auto& base = container.base;
65
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("one"));
66
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("two"));
67
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("three"));
68
69 // Copying a container of pointers does not copy the referenced objects.
70
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 auto container_copy = container;
71
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 print(reference(container_copy));
72
73
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 container_copy[0].name() = "alfa";
74
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 container_copy[1].name() = "bravo";
75
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 container_copy[2].name() = "charlie";
76
77
2/10
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
2 EXPECT_EQ(container, container_copy); // shallow copy
78
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
2 EXPECT_NE("one", container[0].name());
79
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
2 EXPECT_NE("two", container[1].name());
80 4 }
81
82 8 TEST(SharedPointerVector, front_back) {
83 // Place elements into container as pointers.
84 2 auto container = SharedPointerVector<Verbose<>>{};
85 2 auto& base = container.base;
86
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("front"));
87
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("middle"));
88
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("back"));
89
90
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
2 EXPECT_EQ("front", container.front().name());
91
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
2 EXPECT_EQ("back", container.back().name());
92 4 }
93
94 8 TEST(SharedPointerVector, erase_if) {
95 2 auto container = SharedPointerVector<Verbose<>>{};
96 2 auto& base = container.base;
97
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("one"));
98
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("two"));
99
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("three"));
100
101 // In order to avoid copying/moving values,
102 // use the base vector of pointers for erase-remove.
103 5 auto predicate = [](const auto& elem) { return elem->name() == "two"; };
104
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 erase_if(base, predicate);
105
106
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 print(reference(container));
107 4 }
108
109 8 TEST(SharedPointerVector, mask) {
110 2 auto container = SharedPointerVector<Verbose<>>{};
111 2 auto& base = container.base;
112
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("one"));
113
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("two"));
114
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_shared<Verbose<>>("three"));
115
116
2/4
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
6 auto masked = mask(container, std::vector<bool>{true, false, true});
117
118
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 masked[1].name() = "tres";
119
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
2 EXPECT_EQ("tres", container[2].name());
120
121
2/10
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
2 EXPECT_EQ(container.size() - 1, masked.size());
122
2/10
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
2 EXPECT_EQ(container[0].name(), masked[0].name());
123
2/10
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
2 EXPECT_EQ(container[2].name(), masked[1].name());
124
125
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 print(reference(container));
126 4 }
127
128 8 TEST(UniquePointerVector, uncopyable) {
129 2 auto container = UniquePointerVector<Verbose<>>{};
130 2 auto& base = container.base;
131
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_unique<Verbose<>>("one"));
132
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_unique<Verbose<>>("two"));
133
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 base.emplace_back(std::make_unique<Verbose<>>("three"));
134
135 // auto container_copy = container; // compile time error
136 4 }
137