blob: 7f1d09d393f13984a1a0d4a59926e6c8334d71dd (
plain) (
blame)
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
|
#pragma once
namespace WAVM {
// A smart pointer that uses an intrusive reference counter.
// Needs Pointee to define memory functions to manipulate the reference count:
// void addRef();
// void removeRef();
template<typename Pointee> struct IntrusiveSharedPtr
{
// Constructors/destructor
constexpr IntrusiveSharedPtr() : value(nullptr) {}
IntrusiveSharedPtr(Pointee* inValue)
{
value = inValue;
if(value) { value->addRef(); }
}
IntrusiveSharedPtr(const IntrusiveSharedPtr<Pointee>& inCopy)
{
value = inCopy.value;
if(value) { value->addRef(); }
}
IntrusiveSharedPtr(IntrusiveSharedPtr<Pointee>&& inMove) noexcept
{
value = inMove.value;
inMove.value = nullptr;
}
~IntrusiveSharedPtr()
{
if(value) { value->removeRef(); }
}
// Adopt a raw pointer: coerces the pointer to an IntrusiveSharedPtr without calling addRef
// or removeRef.
static IntrusiveSharedPtr<Pointee> adopt(Pointee*&& inValue)
{
IntrusiveSharedPtr<Pointee> result(adoptConstructorSelector, inValue);
inValue = nullptr;
return result;
}
// Assignment operators
void operator=(Pointee* inValue)
{
auto oldValue = value;
value = inValue;
if(value) { value->addRef(); }
if(oldValue) { oldValue->removeRef(); }
}
void operator=(const IntrusiveSharedPtr<Pointee>& inCopy)
{
auto oldValue = value;
value = inCopy.value;
if(value) { value->addRef(); }
if(oldValue) { oldValue->removeRef(); }
}
void operator=(IntrusiveSharedPtr<Pointee>&& inMove) noexcept
{
auto oldValue = value;
value = inMove.value;
inMove.value = nullptr;
if(oldValue) { oldValue->removeRef(); }
}
// Accessors
constexpr operator Pointee*() const { return value; }
constexpr Pointee& operator*() const { return *value; }
constexpr Pointee* operator->() const { return value; }
private:
Pointee* value;
enum AdoptConstructorSelector
{
adoptConstructorSelector
};
constexpr IntrusiveSharedPtr(AdoptConstructorSelector, Pointee* inValue) : value(inValue) {}
};
}
|