blob: 24648e623444e6926d8530fd50f69b4cb7256893 (
plain)
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
// Copyright 2009-2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "atomic.h"
namespace embree
{
struct NullTy {
};
extern MAYBE_UNUSED NullTy null;
class RefCount
{
public:
RefCount(int val = 0) : refCounter(val) {}
virtual ~RefCount() {};
virtual RefCount* refInc() { refCounter.fetch_add(1); return this; }
virtual void refDec() { if (refCounter.fetch_add(-1) == 1) delete this; }
private:
std::atomic<size_t> refCounter;
};
////////////////////////////////////////////////////////////////////////////////
/// Reference to single object
////////////////////////////////////////////////////////////////////////////////
template<typename Type>
class Ref
{
public:
Type* ptr;
////////////////////////////////////////////////////////////////////////////////
/// Constructors, Assignment & Cast Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline Ref() : ptr(nullptr) {}
__forceinline Ref(NullTy) : ptr(nullptr) {}
__forceinline Ref(const Ref& input) : ptr(input.ptr) { if (ptr) ptr->refInc(); }
__forceinline Ref(Ref&& input) : ptr(input.ptr) { input.ptr = nullptr; }
__forceinline Ref(Type* const input) : ptr(input)
{
if (ptr)
ptr->refInc();
}
__forceinline ~Ref()
{
if (ptr)
ptr->refDec();
}
__forceinline Ref& operator =(const Ref& input)
{
if (input.ptr)
input.ptr->refInc();
if (ptr)
ptr->refDec();
ptr = input.ptr;
return *this;
}
__forceinline Ref& operator =(Ref&& input)
{
if (ptr)
ptr->refDec();
ptr = input.ptr;
input.ptr = nullptr;
return *this;
}
__forceinline Ref& operator =(Type* const input)
{
if (input)
input->refInc();
if (ptr)
ptr->refDec();
ptr = input;
return *this;
}
__forceinline Ref& operator =(NullTy)
{
if (ptr)
ptr->refDec();
ptr = nullptr;
return *this;
}
__forceinline operator bool() const { return ptr != nullptr; }
__forceinline const Type& operator *() const { return *ptr; }
__forceinline Type& operator *() { return *ptr; }
__forceinline const Type* operator ->() const { return ptr; }
__forceinline Type* operator ->() { return ptr; }
template<typename TypeOut>
__forceinline Ref<TypeOut> cast() { return Ref<TypeOut>(static_cast<TypeOut*>(ptr)); }
template<typename TypeOut>
__forceinline const Ref<TypeOut> cast() const { return Ref<TypeOut>(static_cast<TypeOut*>(ptr)); }
template<typename TypeOut>
__forceinline Ref<TypeOut> dynamicCast() { return Ref<TypeOut>(dynamic_cast<TypeOut*>(ptr)); }
template<typename TypeOut>
__forceinline const Ref<TypeOut> dynamicCast() const { return Ref<TypeOut>(dynamic_cast<TypeOut*>(ptr)); }
};
template<typename Type> __forceinline bool operator < (const Ref<Type>& a, const Ref<Type>& b) { return a.ptr < b.ptr; }
template<typename Type> __forceinline bool operator ==(const Ref<Type>& a, NullTy ) { return a.ptr == nullptr; }
template<typename Type> __forceinline bool operator ==(NullTy , const Ref<Type>& b) { return nullptr == b.ptr; }
template<typename Type> __forceinline bool operator ==(const Ref<Type>& a, const Ref<Type>& b) { return a.ptr == b.ptr; }
template<typename Type> __forceinline bool operator !=(const Ref<Type>& a, NullTy ) { return a.ptr != nullptr; }
template<typename Type> __forceinline bool operator !=(NullTy , const Ref<Type>& b) { return nullptr != b.ptr; }
template<typename Type> __forceinline bool operator !=(const Ref<Type>& a, const Ref<Type>& b) { return a.ptr != b.ptr; }
}
|