Directory: | cvmfs/ |
---|---|
File: | cvmfs/util/shared_ptr.h |
Date: | 2025-02-09 02:34:19 |
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 | 639 | SharedPtr() { // never throws | |
22 | 639 | value_ = NULL; | |
23 | 639 | count_ = NULL; | |
24 | 639 | } | |
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 | 706 | ~SharedPtr() { // never throws | |
34 |
2/2✓ Branch 0 taken 68 times.
✓ Branch 1 taken 316 times.
|
706 | 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 | 706 | } | |
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 | 552 | int64_t UseCount() const { // never throws | |
123 | 552 | 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 |