GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/util/shared_ptr.h
Date: 2026-10-25 02:40:14
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 20015 SharedPtr() { // never throws
22 20015 value_ = NULL;
23 20015 count_ = NULL;
24 20015 }
25
26 template<class Y>
27 582 explicit SharedPtr(Y *p) {
28 582 value_ = static_cast<element_type *>(p);
29 582 count_ = new std::atomic<int64_t>;
30 582 count_->store(1);
31 582 }
32
33 21094 ~SharedPtr() { // never throws
34
2/2
✓ Branch 0 taken 942 times.
✓ Branch 1 taken 9974 times.
21094 if (count_) {
35 1146 count_->fetch_sub(1);
36
2/2
✓ Branch 1 taken 325 times.
✓ Branch 2 taken 617 times.
2292 if (count_->load() == 0) {
37
1/2
✓ Branch 0 taken 325 times.
✗ Branch 1 not taken.
461 delete value_;
38
1/2
✓ Branch 0 taken 325 times.
✗ Branch 1 not taken.
461 delete count_;
39 }
40 }
41 21094 }
42
43 672 SharedPtr(SharedPtr const &r)
44 672 : value_(r.value_), count_(r.count_) { // never throws
45
1/2
✓ Branch 0 taken 570 times.
✗ Branch 1 not taken.
672 if (count_) {
46 672 count_->fetch_add(1);
47 }
48 672 }
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 5091 SharedPtr &operator=(SharedPtr const &r) { // never throws
59
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2603 times.
5091 if (this == &r)
60 ✗ return *this;
61
62 5091 Reset();
63 5091 value_ = r.value_;
64 5091 count_ = r.count_;
65
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 2488 times.
5091 if (count_) {
66 115 count_->fetch_add(1);
67 }
68 5091 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 5159 void Reset() { // never throws
83
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2585 times.
5159 if (count_) {
84 86 count_->fetch_sub(1);
85
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 68 times.
172 if (count_->load() == 0) {
86
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 delete value_;
87
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 delete count_;
88 }
89 86 value_ = NULL;
90 86 count_ = NULL;
91 }
92 5159 }
93
94 template<class Y>
95 34 void Reset(Y *p) {
96 34 Reset();
97 34 value_ = static_cast<element_type *>(p);
98 34 count_ = new std::atomic<int64_t>;
99 34 count_->store(1);
100 34 }
101
102 ✗ T &operator*() const { // never throws
103 ✗ return *value_;
104 }
105
106 891 T *operator->() const { // never throws
107 891 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 306 bool Unique() const { // never throws
117
3/4
✓ Branch 0 taken 306 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 204 times.
✓ Branch 4 taken 102 times.
612 return count_ && (count_->load() == 1);
118 }
119
120 17367 int64_t UseCount() const { // never throws
121 17673 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