GCC Code Coverage Report


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