GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/util/shared_ptr.h Lines: 41 52 78.8 %
Date: 2019-02-03 02:48:13 Branches: 18 30 60.0 %

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 "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
  SharedPtr() {  // never throws
22
    value_ = NULL;
23
    count_ = NULL;
24
  }
25
26
  template <class Y>
27
3
  explicit SharedPtr(Y* p) {
28
3
    value_ = static_cast<element_type*>(p);
29
3
    count_ = new atomic_int64;
30
3
    atomic_write64(count_, 1);
31
3
  }
32
33
6
  ~SharedPtr() {  // never throws
34

6
    if (count_) {
35
6
      atomic_dec64(count_);
36

6
      if (atomic_read64(count_) == 0) {
37
4
        delete value_;
38
4
        delete count_;
39
      }
40
    }
41
6
  }
42
43
3
  SharedPtr(SharedPtr const& r)
44
3
      : value_(r.value_), count_(r.count_) {  // never throws
45

3
    if (count_) {
46
3
      atomic_inc64(count_);
47
    }
48
3
  }
49
50
  template <class Y>
51
  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
1
  SharedPtr& operator=(SharedPtr const& r) {  // never throws
59
1
    Reset();
60
1
    value_ = r.value_;
61
1
    count_ = r.count_;
62
1
    if (count_) {
63
1
      atomic_inc64(count_);
64
    }
65
1
    return *this;
66
  }
67
68
  template <class Y>
69
  SharedPtr& operator=(SharedPtr<Y> const& r) {  // never throws
70
    Reset();
71
    value_ = r.value_;
72
    count_ = r.count_;
73
    if (count_) {
74
      atomic_inc64(count_);
75
    }
76
    return *this;
77
  }
78
79
3
  void Reset() {  // never throws
80
3
    if (count_) {
81
2
      atomic_dec64(count_);
82
2
      if (atomic_read64(count_) == 0) {
83
        delete value_;
84
        delete count_;
85
      }
86
2
      value_ = NULL;
87
2
      count_ = NULL;
88
    }
89
3
  }
90
91
  template <class Y>
92
1
  void Reset(Y* p) {
93
1
    Reset();
94
1
    value_ = static_cast<element_type*>(p);
95
1
    count_ = new atomic_int64;
96
1
    atomic_write64(count_, 1);
97
1
  }
98
99
  T& operator*() const {  // never throws
100
    return *value_;
101
  }
102
103
  T* operator->() const {  // never throws
104
    return value_;
105
  }
106
107
  element_type* Get() const {  // never throws
108
    return value_;
109
  }
110
111
9
  bool Unique() const {  // never throws
112

9
    return count_ && (atomic_read64(count_) == 1);
113
  }
114
115
9
  int64_t UseCount() const {  // never throws
116

9
    return count_ ? atomic_read64(count_) : -1;
117
  }
118
119
  operator void*() const {  // never throws
120
    return static_cast<void*>(value_);
121
  }
122
123
 private:
124
  element_type* value_;
125
  atomic_int64* count_;
126
};
127
128
template <class T, class U>
129
bool operator==(SharedPtr<T> const& a,
130
                SharedPtr<U> const& b) {  // never throws
131
  return a.value_ == b.value_;
132
}
133
134
template <class T, class U>
135
bool operator!=(SharedPtr<T> const& a,
136
                SharedPtr<U> const& b) {  // never throws
137
  return a.value_ != b.value_;
138
}
139
140
template <class T, class U>
141
bool operator<(SharedPtr<T> const& a, SharedPtr<U> const& b) {  // never throws
142
  return a.value_ < b.value_;
143
}
144
145
template <class T>
146
typename SharedPtr<T>::element_type* GetPointer(
147
    SharedPtr<T> const& p) {  // never throws
148
  return p.value_;
149
}
150
151
template <class T, class U>
152
SharedPtr<T> StaticPointerCast(SharedPtr<U> const& r) {  // never throws
153
  return SharedPtr<T>(static_cast<T*>(r.value_));
154
}
155
156
template <class T, class U>
157
SharedPtr<T> ConstPointerCast(SharedPtr<U> const& r) {  // never throws
158
  return SharedPtr<T>(const_cast<T*>(r.value_));
159
}
160
161
template <class T, class U>
162
SharedPtr<T> DynamicPointerCast(SharedPtr<U> const& r) {  // never throws
163
  return SharedPtr<T>(dynamic_cast<T*>(r.value_));
164
}
165
166
template <class T, class U>
167
SharedPtr<T> ReinterpretPointerCast(SharedPtr<U> const& r) {  // never throws
168
  return SharedPtr<T>(reinterpret_cast<T*>(r.value_));
169
}
170
171
#ifdef CVMFS_NAMESPACE_GUARD
172
}  // namespace CVMFS_NAMESPACE_GUARD
173
#endif
174
175
#endif  // CVMFS_UTIL_SHARED_PTR_H_