GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/util/shared_ptr.h
Date: 2026-02-01 02:35:56
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 <cstdint>
9 #include <cstdlib>
10
11 #include "util/atomic.h"
12
13 #ifdef CVMFS_NAMESPACE_GUARD
14 namespace CVMFS_NAMESPACE_GUARD {
15 #endif // CVMFS_NAMESPACE_GUARD
16
17 template<typename T>
18 class SharedPtr {
19 public:
20 typedef T element_type;
21
22 19286 SharedPtr() { // never throws
23 19286 value_ = NULL;
24 19286 count_ = NULL;
25 19286 }
26
27 template<class Y>
28 1152 explicit SharedPtr(Y *p) {
29 1152 value_ = static_cast<element_type *>(p);
30 1152 count_ = new atomic_int64;
31 1152 atomic_write64(count_, 1);
32 1152 }
33
34 20956 ~SharedPtr() { // never throws
35
2/2
✓ Branch 0 taken 1872 times.
✓ Branch 1 taken 9536 times.
20956 if (count_) {
36 1884 atomic_dec64(count_);
37
2/2
✓ Branch 1 taken 518 times.
✓ Branch 2 taken 1354 times.
1884 if (atomic_read64(count_) == 0) {
38
1/2
✓ Branch 0 taken 518 times.
✗ Branch 1 not taken.
526 delete value_;
39
1/2
✓ Branch 0 taken 518 times.
✗ Branch 1 not taken.
526 delete count_;
40 }
41 }
42 20956 }
43
44 1092 SharedPtr(SharedPtr const &r)
45 1092 : value_(r.value_), count_(r.count_) { // never throws
46
1/2
✓ Branch 0 taken 1086 times.
✗ Branch 1 not taken.
1092 if (count_) {
47 1092 atomic_inc64(count_);
48 }
49 1092 }
50
51 template<class Y>
52 explicit SharedPtr(SharedPtr<Y> const &r)
53 : value_(r.value_), count_(r.count_) { // never throws
54 if (count_) {
55 atomic_inc64(count_);
56 }
57 }
58
59 3368 SharedPtr &operator=(SharedPtr const &r) { // never throws
60
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1820 times.
3368 if (this == &r)
61 return *this;
62
63 3368 Reset();
64 3368 value_ = r.value_;
65 3368 count_ = r.count_;
66
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 1548 times.
3368 if (count_) {
67 272 atomic_inc64(count_);
68 }
69 3368 return *this;
70 }
71
72 template<class Y>
73 SharedPtr &operator=(SharedPtr<Y> const &r) { // never throws
74 Reset();
75 value_ = r.Get();
76 count_ = r.GetCountPtr();
77 if (count_) {
78 atomic_inc64(count_);
79 }
80 return *this;
81 }
82
83 3372 void Reset() { // never throws
84
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 1760 times.
3372 if (count_) {
85 64 atomic_dec64(count_);
86
2/2
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 4 times.
64 if (atomic_read64(count_) == 0) {
87
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 delete value_;
88
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 delete count_;
89 }
90 64 value_ = NULL;
91 64 count_ = NULL;
92 }
93 3372 }
94
95 template<class Y>
96 2 void Reset(Y *p) {
97 2 Reset();
98 2 value_ = static_cast<element_type *>(p);
99 2 count_ = new atomic_int64;
100 2 atomic_write64(count_, 1);
101 2 }
102
103 T &operator*() const { // never throws
104 return *value_;
105 }
106
107 2850 T *operator->() const { // never throws
108 2850 return value_;
109 }
110
111 element_type *Get() const { // never throws
112 return value_;
113 }
114
115 atomic_int64 *GetCountPtr() const { return count_; }
116
117 18 bool Unique() const { // never throws
118
3/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 6 times.
18 return count_ && (atomic_read64(count_) == 1);
119 }
120
121 16669 int64_t UseCount() const { // never throws
122 16669 return count_ ? atomic_read64(count_) : -1;
123 }
124
125 private:
126 element_type *value_;
127 atomic_int64 *count_;
128 };
129
130 template<class T, class U>
131 bool operator==(SharedPtr<T> const &a,
132 SharedPtr<U> const &b) { // never throws
133 return a.value_ == b.value_;
134 }
135
136 template<class T, class U>
137 bool operator!=(SharedPtr<T> const &a,
138 SharedPtr<U> const &b) { // never throws
139 return a.value_ != b.value_;
140 }
141
142 template<class T, class U>
143 bool operator<(SharedPtr<T> const &a, SharedPtr<U> const &b) { // never throws
144 return a.value_ < b.value_;
145 }
146
147 template<class T>
148 typename SharedPtr<T>::element_type *GetPointer(
149 SharedPtr<T> const &p) { // never throws
150 return p.value_;
151 }
152
153 template<class T, class U>
154 SharedPtr<T> StaticPointerCast(SharedPtr<U> const &r) { // never throws
155 return SharedPtr<T>(static_cast<T *>(r.value_));
156 }
157
158 template<class T, class U>
159 SharedPtr<T> ConstPointerCast(SharedPtr<U> const &r) { // never throws
160 return SharedPtr<T>(const_cast<T *>(r.value_));
161 }
162
163 template<class T, class U>
164 SharedPtr<T> DynamicPointerCast(SharedPtr<U> const &r) { // never throws
165 return SharedPtr<T>(dynamic_cast<T *>(r.value_));
166 }
167
168 template<class T, class U>
169 SharedPtr<T> ReinterpretPointerCast(SharedPtr<U> const &r) { // never throws
170 return SharedPtr<T>(reinterpret_cast<T *>(r.value_));
171 }
172
173 #ifdef CVMFS_NAMESPACE_GUARD
174 } // namespace CVMFS_NAMESPACE_GUARD
175 #endif
176
177 #endif // CVMFS_UTIL_SHARED_PTR_H_
178