-
Notifications
You must be signed in to change notification settings - Fork 4
/
refcount.h
89 lines (76 loc) · 1.49 KB
/
refcount.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#ifndef REF_COUNT_H
#define REF_COUNT_H
// Reference counting smart pointer
template <class T> class ref_count {
struct capsule {
T *data;
int count;
};
capsule *p;
void release()
{
if( p!=NULL && (--p->count)==0 ) {
delete p->data;
delete p;
}
p=NULL;
}
public:
ref_count<T>() : p(NULL)
{
}
ref_count<T>( const ref_count<T> &rhs ) : p(rhs.p)
{
if( p!=NULL ) {
p->count++;
}
}
explicit ref_count<T>( T *data ) : p(new capsule)
{
if( p!=NULL ) {
p->data=data;
p->count=1;
} else {
// Our allocation failed, but the called relied on us to release their pointer when we're done
delete data;
}
}
~ref_count<T>()
{
release();
}
ref_count<T> &operator=( const ref_count &rhs )
{
release();
p=rhs.p;
if( p!=NULL ) {
p->count++;
}
return *this;
}
operator T* ()
{
return p!=NULL ? p->data : NULL;
}
operator const T*() const
{
return p!=NULL ? p->data : NULL;
}
T *operator ->()
{
return *this;
}
const T *operator ->() const
{
return *this;
}
T &operator *()
{
return *static_cast<T *>(*this);
}
const T &operator *() const
{
return *static_cast<const T *>(*this);
}
};
#endif // REF_COUNT_H