GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/util/shared_ptr.h
Date: 2026-10-11 02:40:02
Exec Total Coverage
Lines: 50 55 90.9%
Branches: 19 26 73.1%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_UTIL_SHARED_PTR_H_
6 #define CVMFS_UTIL_SHARED_PTR_H_
7
8 #include <atomic>
9 #include <cstdint>
10 #include <cstdlib>
11
12 #ifdef CVMFS_NAMESPACE_GUARD
13 namespace CVMFS_NAMESPACE_GUARD {
14 #endif // CVMFS_NAMESPACE_GUARD
15
16 template<typename T>
17 class SharedPtr {
18 public:
19 typedef T element_type;
20
21 18742 SharedPtr() { // never throws
22 18742 value_ = NULL;
23 18742 count_ = NULL;
24 18742 }
25
26 template<class Y>
27 288 explicit SharedPtr(Y *p) {
28 288 value_ = static_cast<element_type *>(p);
29 288 count_ = new std::atomic<int64_t>;
30 288 count_->store(1);
31 288 }
32
33 19260 ~SharedPtr() { // never throws
34
2/2
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 9348 times.
19260 if (count_) {
35 564 count_->fetch_sub(1);
36
2/2
✓ Branch 1 taken 150 times.
✓ Branch 2 taken 378 times.
1128 if (count_->load() == 0) {
37
1/2
✓ Branch 0 taken 150 times.
✗ Branch 1 not taken.
174 delete value_;
38
1/2
✓ Branch 0 taken 150 times.
✗ Branch 1 not taken.
174 delete count_;
39 }
40 }
41 19260 }
42
43 348 SharedPtr(SharedPtr const &r)
44 348 : value_(r.value_), count_(r.count_) { // never throws
45
1/2
✓ Branch 0 taken 330 times.
✗ Branch 1 not taken.
348 if (count_) {
46 348 count_->fetch_add(1);
47 }
48 348 }
49
50 template<class Y>
51 explicit SharedPtr(SharedPtr<Y> const &r)
52 : value_(r.value_), count_(r.count_) { // never throws
53 if (count_) {
54 count_->fetch_add(1);
55 }
56 }
57
58 3636 SharedPtr &operator=(SharedPtr const &r) { // never throws
59
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1848 times.
3636 if (this == &r)
60 ✗ return *this;
61
62 3636 Reset();
63 3636 value_ = r.value_;
64 3636 count_ = r.count_;
65
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 1788 times.
3636 if (count_) {
66 60 count_->fetch_add(1);
67 }
68 3636 return *this;
69 }
70
71 template<class Y>
72 SharedPtr &operator=(SharedPtr<Y> const &r) { // never throws
73 Reset();
74 value_ = r.Get();
75 count_ = r.GetCountPtr();
76 if (count_) {
77 count_->fetch_add(1);
78 }
79 return *this;
80 }
81
82 3648 void Reset() { // never throws
83
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 1836 times.
3648 if (count_) {
84 24 count_->fetch_sub(1);
85
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 12 times.
48 if (count_->load() == 0) {
86
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 delete value_;
87
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 delete count_;
88 }
89 24 value_ = NULL;
90 24 count_ = NULL;
91 }
92 3648 }
93
94 template<class Y>
95 6 void Reset(Y *p) {
96 6 Reset();
97 6 value_ = static_cast<element_type *>(p);
98 6 count_ = new std::atomic<int64_t>;
99 6 count_->store(1);
100 6 }
101
102 ✗ T &operator*() const { // never throws
103 ✗ return *value_;
104 }
105
106 594 T *operator->() const { // never throws
107 594 return value_;
108 }
109
110 ✗ element_type *Get() const { // never throws
111 ✗ return value_;
112 }
113
114 std::atomic<int64_t> *GetCountPtr() const { return count_; }
115
116 54 bool Unique() const { // never throws
117
3/4
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 18 times.
108 return count_ && (count_->load() == 1);
118 }
119
120 15879 int64_t UseCount() const { // never throws
121 15933 return count_ ? count_->load() : -1;
122 }
123
124 private:
125 element_type *value_;
126 std::atomic<int64_t> *count_;
127 };
128
129 template<class T, class U>
130 bool operator==(SharedPtr<T> const &a,
131 SharedPtr<U> const &b) { // never throws
132 return a.value_ == b.value_;
133 }
134
135 template<class T, class U>
136 bool operator!=(SharedPtr<T> const &a,
137 SharedPtr<U> const &b) { // never throws
138 return a.value_ != b.value_;
139 }
140
141 template<class T, class U>
142 bool operator<(SharedPtr<T> const &a, SharedPtr<U> const &b) { // never throws
143 return a.value_ < b.value_;
144 }
145
146 template<class T>
147 typename SharedPtr<T>::element_type *GetPointer(
148 SharedPtr<T> const &p) { // never throws
149 return p.value_;
150 }
151
152 template<class T, class U>
153 SharedPtr<T> StaticPointerCast(SharedPtr<U> const &r) { // never throws
154 return SharedPtr<T>(static_cast<T *>(r.value_));
155 }
156
157 template<class T, class U>
158 SharedPtr<T> ConstPointerCast(SharedPtr<U> const &r) { // never throws
159 return SharedPtr<T>(const_cast<T *>(r.value_));
160 }
161
162 template<class T, class U>
163 SharedPtr<T> DynamicPointerCast(SharedPtr<U> const &r) { // never throws
164 return SharedPtr<T>(dynamic_cast<T *>(r.value_));
165 }
166
167 template<class T, class U>
168 SharedPtr<T> ReinterpretPointerCast(SharedPtr<U> const &r) { // never throws
169 return SharedPtr<T>(reinterpret_cast<T *>(r.value_));
170 }
171
172 #ifdef CVMFS_NAMESPACE_GUARD
173 } // namespace CVMFS_NAMESPACE_GUARD
174 #endif
175
176 #endif // CVMFS_UTIL_SHARED_PTR_H_
177
178