GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/util/shared_ptr.h
Date: 2026-05-24 02:35:55
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 14658 SharedPtr() { // never throws
23 14658 value_ = NULL;
24 14658 count_ = NULL;
25 14658 }
26
27 template<class Y>
28 186 explicit SharedPtr(Y *p) {
29 186 value_ = static_cast<element_type *>(p);
30 186 count_ = new atomic_int64;
31 186 atomic_write64(count_, 1);
32 186 }
33
34 15008 ~SharedPtr() { // never throws
35
2/2
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 7320 times.
15008 if (count_) {
36 368 atomic_dec64(count_);
37
2/2
✓ Branch 1 taken 110 times.
✓ Branch 2 taken 156 times.
368 if (atomic_read64(count_) == 0) {
38
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
178 delete value_;
39
1/2
✓ Branch 0 taken 110 times.
✗ Branch 1 not taken.
178 delete count_;
40 }
41 }
42 15008 }
43
44 206 SharedPtr(SharedPtr const &r)
45 206 : value_(r.value_), count_(r.count_) { // never throws
46
1/2
✓ Branch 0 taken 155 times.
✗ Branch 1 not taken.
206 if (count_) {
47 206 atomic_inc64(count_);
48 }
49 206 }
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 3567 SharedPtr &operator=(SharedPtr const &r) { // never throws
60
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1801 times.
3567 if (this == &r)
61 return *this;
62
63 3567 Reset();
64 3567 value_ = r.value_;
65 3567 count_ = r.count_;
66
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 1766 times.
3567 if (count_) {
67 35 atomic_inc64(count_);
68 }
69 3567 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 3601 void Reset() { // never throws
84
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1797 times.
3601 if (count_) {
85 38 atomic_dec64(count_);
86
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 34 times.
38 if (atomic_read64(count_) == 0) {
87
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 delete value_;
88
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 delete count_;
89 }
90 38 value_ = NULL;
91 38 count_ = NULL;
92 }
93 3601 }
94
95 template<class Y>
96 17 void Reset(Y *p) {
97 17 Reset();
98 17 value_ = static_cast<element_type *>(p);
99 17 count_ = new atomic_int64;
100 17 atomic_write64(count_, 1);
101 17 }
102
103 T &operator*() const { // never throws
104 return *value_;
105 }
106
107 198 T *operator->() const { // never throws
108 198 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 153 bool Unique() const { // never throws
118
3/4
✓ Branch 0 taken 153 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 102 times.
✓ Branch 4 taken 51 times.
153 return count_ && (atomic_read64(count_) == 1);
119 }
120
121 12889 int64_t UseCount() const { // never throws
122 12889 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