knowL: Knowledge Libraries
Loading...
Searching...
No Matches
SharedRef.h
1#include <atomic>
2
3namespace knowCore
4{
5 namespace details
6 {
8 {
9 template<typename _T_>
10 static bool canDelete(_T_*)
11 {
12 return true;
13 }
14 };
15 }
20 template<typename _T_, typename _TDeleteCheck_ = details::SharedRefDefaultCheck>
22 {
23 template<typename _TOther_, typename _TDeleteCheckOther_>
24 friend class SharedRef;
25 public:
26 typedef _T_ ElementType;
27 public:
28 SharedRef() : m_data(nullptr)
29 {
30 }
34 SharedRef(_T_* _t, bool _own) : m_data(new Data)
35 {
36 m_data->t = _t;
37 ++m_data->count;
38 m_data->own = _own;
39 }
40 SharedRef(const SharedRef<_T_, _TDeleteCheck_>& _rhs) : m_data(nullptr) { ref(_rhs);
41 }
42 SharedRef& operator=(const SharedRef<_T_, _TDeleteCheck_>& _rhs)
43 {
44 if(_rhs.m_data != m_data)
45 {
46 deref();
47 ref(_rhs);
48 }
49 return *this;
50 }
51 ~SharedRef()
52 {
53 deref();
54 }
55 public: // Casting operator
59 template<typename _TCast_>
61 {
62 using CastSharedRef = SharedRef<_TCast_, _TDeleteCheck_>;
63 CastSharedRef res;
64 if(m_data and dynamic_cast<_TCast_*>(m_data->t))
65 {
66 res.m_data = reinterpret_cast<typename CastSharedRef::Data*>(m_data); // a bit ugly but all Data have the same layout
67 ++m_data->count;
68 }
69 return res;
70 }
74 template<typename _TCast_, std::enable_if_t<std::is_base_of_v<_TCast_, _T_>, bool> = true>
76 {
77 using CastSharedRef = SharedRef<_TCast_, _TDeleteCheck_>;
78 CastSharedRef res;
79 if(m_data)
80 {
81 res.m_data = reinterpret_cast<typename CastSharedRef::Data*>(m_data); // a bit ugly but all Data have the same layout
82 ++m_data->count;
83 }
84 return res;
85 }
86 public: // Comparison operator
87 bool operator==(const SharedRef<_T_>& _rhs) const
88 {
89 return m_data == _rhs.m_data or m_data->t == _rhs.m_data->t;
90 }
91 bool operator==(const _T_* _rhs) const
92 {
93 return (m_data and m_data->t == _rhs) or (not m_data and not _rhs);
94 }
95 operator bool () const
96 {
97 return m_data and m_data->t;
98 }
99 public: // Access operator
100 bool isValid() const
101 {
102 return m_data and m_data->t;
103 }
104 _T_* operator->()
105 {
106 return m_data->t;
107 }
108 const _T_* operator->() const
109 {
110 return m_data->t;
111 }
115 _T_* grab()
116 {
117 m_data->own = false;
118 return m_data->t;
119 }
120 _T_* data()
121 {
122 return m_data->t;
123 }
124 const _T_* data() const
125 {
126 return m_data->t;
127 }
128 private:
129 void deref()
130 {
131 if(m_data)
132 {
133 --m_data->count;
134 if(m_data->count == 0)
135 {
136 if(m_data->own and _TDeleteCheck_::canDelete(m_data->t))
137 {
138 delete m_data->t;
139 }
140 delete m_data;
141 }
142 m_data = nullptr;
143 }
144 }
145 void ref(const SharedRef<_T_, _TDeleteCheck_>& _rhs)
146 {
147 m_data = _rhs.m_data;
148 if(m_data)
149 {
150 ++m_data->count;
151 }
152 }
153 private:
154 struct Data
155 {
156 Data() : count(0) {}
157 Data(const Data& _rhs) = delete;
158 _T_* t = nullptr;
159 std::atomic<int> count;
160 bool own = false;
161 };
162 Data* m_data;
163 };
164}
Definition SharedRef.h:22
SharedRef< _TCast_, _TDeleteCheck_ > d_cast() const
Definition SharedRef.h:60
SharedRef(_T_ *_t, bool _own)
Definition SharedRef.h:34
_T_ * grab()
Definition SharedRef.h:115
SharedRef< _TCast_, _TDeleteCheck_ > s_cast() const
Definition SharedRef.h:75