GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/util/shared_ptr.h
Date: 2026-03-15 02:35:27
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 20182 SharedPtr() { // never throws
23 20182 value_ = NULL;
24 20182 count_ = NULL;
25 20182 }
26
27 template<class Y>
28 1026 explicit SharedPtr(Y *p) {
29 1026 value_ = static_cast<element_type *>(p);
30 1026 count_ = new atomic_int64;
31 1026 atomic_write64(count_, 1);
32 1026 }
33
34 22068 ~SharedPtr() { // never throws
35
2/2
✓ Branch 0 taken 1746 times.
✓ Branch 1 taken 10026 times.
22068 if (count_) {
36 2016 atomic_dec64(count_);
37
2/2
✓ Branch 1 taken 558 times.
✓ Branch 2 taken 1188 times.
2016 if (atomic_read64(count_) == 0) {
38
1/2
✓ Branch 0 taken 558 times.
✗ Branch 1 not taken.
738 delete value_;
39
1/2
✓ Branch 0 taken 558 times.
✗ Branch 1 not taken.
738 delete count_;
40 }
41 }
42 22068 }
43
44 1206 SharedPtr(SharedPtr const &r)
45 1206 : value_(r.value_), count_(r.count_) { // never throws
46
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1206 if (count_) {
47 1206 atomic_inc64(count_);
48 }
49 1206 }
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 5711 SharedPtr &operator=(SharedPtr const &r) { // never throws
60
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2959 times.
5711 if (this == &r)
61 return *this;
62
63 5711 Reset();
64 5711 value_ = r.value_;
65 5711 count_ = r.count_;
66
2/2
✓ Branch 0 taken 207 times.
✓ Branch 1 taken 2752 times.
5711 if (count_) {
67 207 atomic_inc64(count_);
68 }
69 5711 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 5801 void Reset() { // never throws
84
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 2923 times.
5801 if (count_) {
85 126 atomic_dec64(count_);
86
2/2
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 90 times.
126 if (atomic_read64(count_) == 0) {
87
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 delete value_;
88
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 delete count_;
89 }
90 126 value_ = NULL;
91 126 count_ = NULL;
92 }
93 5801 }
94
95 template<class Y>
96 45 void Reset(Y *p) {
97 45 Reset();
98 45 value_ = static_cast<element_type *>(p);
99 45 count_ = new atomic_int64;
100 45 atomic_write64(count_, 1);
101 45 }
102
103 T &operator*() const { // never throws
104 return *value_;
105 }
106
107 1782 T *operator->() const { // never throws
108 1782 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 405 bool Unique() const { // never throws
118
3/4
✓ Branch 0 taken 405 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 270 times.
✓ Branch 4 taken 135 times.
405 return count_ && (atomic_read64(count_) == 1);
119 }
120
121 17021 int64_t UseCount() const { // never throws
122 17021 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