CommonLibSSE NG
Loading...
Searching...
No Matches
hkRefPtr.h
Go to the documentation of this file.
1#pragma once
2
3namespace RE
4{
5 template <class T>
6 class hkRefPtr
7 {
8 public:
9 using element_type = T;
10
11 // 1
12 inline constexpr hkRefPtr() noexcept :
13 _ptr(nullptr)
14 {}
15
16 // 2
17 inline constexpr hkRefPtr(std::nullptr_t) noexcept :
18 _ptr(nullptr)
19 {}
20
21 // 3
22 template <
23 class Y,
24 std::enable_if_t<
25 std::is_convertible_v<
26 Y*,
28 int> = 0>
29 inline explicit hkRefPtr(Y* a_rhs) :
30 _ptr(a_rhs)
31 {
32 TryAttach();
33 }
34
35 // 9a
36 inline hkRefPtr(const hkRefPtr& a_rhs) :
37 _ptr(a_rhs._ptr)
38 {
39 TryAttach();
40 }
41
42 // 9b
43 template <
44 class Y,
45 std::enable_if_t<
46 std::is_convertible_v<
47 Y*,
49 int> = 0>
50 inline hkRefPtr(const hkRefPtr<Y>& a_rhs) :
51 _ptr(a_rhs._ptr)
52 {
53 TryAttach();
54 }
55
56 // 10a
57 inline hkRefPtr(hkRefPtr&& a_rhs) noexcept :
58 _ptr(std::move(a_rhs._ptr))
59 {
60 a_rhs._ptr = nullptr;
61 }
62
63 // 10b
64 template <
65 class Y,
66 std::enable_if_t<
67 std::is_convertible_v<
68 Y*,
70 int> = 0>
71 inline hkRefPtr(hkRefPtr<Y>&& a_rhs) noexcept :
72 _ptr(std::move(a_rhs._ptr))
73 {
74 a_rhs._ptr = nullptr;
75 }
76
77 inline ~hkRefPtr()
78 {
79 TryDetach();
80 }
81
82 // 1a
83 inline hkRefPtr& operator=(const hkRefPtr& a_rhs)
84 {
85 if (this != std::addressof(a_rhs)) {
86 TryDetach();
87 _ptr = a_rhs._ptr;
88 TryAttach();
89 }
90 return *this;
91 }
92
93 // 1b
94 template <
95 class Y,
96 std::enable_if_t<
97 std::is_convertible_v<
98 Y*,
100 int> = 0>
101 inline hkRefPtr& operator=(const hkRefPtr<Y>& a_rhs)
102 {
103 TryDetach();
104 _ptr = a_rhs._ptr;
105 TryAttach();
106 return *this;
107 }
108
109 // 2a
110 inline hkRefPtr& operator=(hkRefPtr&& a_rhs)
111 {
112 if (this != std::addressof(a_rhs)) {
113 TryDetach();
114 _ptr = std::move(a_rhs._ptr);
115 a_rhs._ptr = nullptr;
116 }
117 return *this;
118 }
119
120 // 2b
121 template <
122 class Y,
123 std::enable_if_t<
124 std::is_convertible_v<
125 Y*,
126 element_type*>,
127 int> = 0>
129 {
130 TryDetach();
131 _ptr = std::move(a_rhs._ptr);
132 a_rhs._ptr = nullptr;
133 return *this;
134 }
135
136 inline void reset()
137 {
138 TryDetach();
139 }
140
141 template <
142 class Y,
143 std::enable_if_t<
144 std::is_convertible_v<
145 Y*,
146 element_type*>,
147 int> = 0>
148 inline void reset(Y* a_ptr)
149 {
150 if (_ptr != a_ptr) {
151 TryDetach();
152 _ptr = a_ptr;
153 TryAttach();
154 }
155 }
156
157 [[nodiscard]] constexpr element_type* get() const noexcept
158 {
159 return _ptr;
160 }
161
162 [[nodiscard]] explicit constexpr operator bool() const noexcept
163 {
164 return static_cast<bool>(_ptr);
165 }
166
167 [[nodiscard]] constexpr element_type& operator*() const noexcept
168 {
169 assert(static_cast<bool>(*this));
170 return *_ptr;
171 }
172
173 [[nodiscard]] constexpr element_type* operator->() const noexcept
174 {
175 assert(static_cast<bool>(*this));
176 return _ptr;
177 }
178
179 protected:
180 template <class>
181 friend class hkRefPtr;
182
184 {
185 if (_ptr) {
186 _ptr->AddReference();
187 }
188 }
189
191 {
192 if (_ptr) {
193 _ptr->RemoveReference();
194 _ptr = nullptr;
195 }
196 }
197
198 // members
200 };
201 static_assert(sizeof(hkRefPtr<void*>) == 0x8);
202
203 template <class T, class... Args>
204 [[nodiscard]] inline hkRefPtr<T> make_hkref(Args&&... a_args)
205 {
206 return hkRefPtr<T>{ new T(std::forward<Args>(a_args)...) };
207 }
208
209 template <class T1, class T2>
210 [[nodiscard]] constexpr bool operator==(const hkRefPtr<T1>& a_lhs, const hkRefPtr<T2>& a_rhs)
211 {
212 return a_lhs.get() == a_rhs.get();
213 }
214
215 template <class T1, class T2>
216 [[nodiscard]] constexpr bool operator!=(const hkRefPtr<T1>& a_lhs, const hkRefPtr<T2>& a_rhs)
217 {
218 return !(a_lhs == a_rhs);
219 }
220
221 template <class T>
222 [[nodiscard]] constexpr bool operator==(const hkRefPtr<T>& a_lhs, std::nullptr_t) noexcept
223 {
224 return !a_lhs;
225 }
226
227 template <class T>
228 [[nodiscard]] constexpr bool operator==(std::nullptr_t, const hkRefPtr<T>& a_rhs) noexcept
229 {
230 return !a_rhs;
231 }
232
233 template <class T>
234 [[nodiscard]] constexpr bool operator!=(const hkRefPtr<T>& a_lhs, std::nullptr_t) noexcept
235 {
236 return static_cast<bool>(a_lhs);
237 }
238
239 template <class T>
240 [[nodiscard]] constexpr bool operator!=(std::nullptr_t, const hkRefPtr<T>& a_rhs) noexcept
241 {
242 return static_cast<bool>(a_rhs);
243 }
244
245 template <class T>
247}
Definition hkRefPtr.h:7
hkRefPtr(const hkRefPtr< Y > &a_rhs)
Definition hkRefPtr.h:50
hkRefPtr(const hkRefPtr &a_rhs)
Definition hkRefPtr.h:36
constexpr element_type * get() const noexcept
Definition hkRefPtr.h:157
T element_type
Definition hkRefPtr.h:9
void reset(Y *a_ptr)
Definition hkRefPtr.h:148
void TryAttach()
Definition hkRefPtr.h:183
void TryDetach()
Definition hkRefPtr.h:190
hkRefPtr(Y *a_rhs)
Definition hkRefPtr.h:29
hkRefPtr(hkRefPtr &&a_rhs) noexcept
Definition hkRefPtr.h:57
~hkRefPtr()
Definition hkRefPtr.h:77
constexpr hkRefPtr() noexcept
Definition hkRefPtr.h:12
constexpr hkRefPtr(std::nullptr_t) noexcept
Definition hkRefPtr.h:17
void reset()
Definition hkRefPtr.h:136
constexpr element_type & operator*() const noexcept
Definition hkRefPtr.h:167
element_type * _ptr
Definition hkRefPtr.h:199
hkRefPtr & operator=(hkRefPtr< Y > &&a_rhs)
Definition hkRefPtr.h:128
hkRefPtr & operator=(const hkRefPtr &a_rhs)
Definition hkRefPtr.h:83
constexpr element_type * operator->() const noexcept
Definition hkRefPtr.h:173
hkRefPtr(hkRefPtr< Y > &&a_rhs) noexcept
Definition hkRefPtr.h:71
hkRefPtr & operator=(const hkRefPtr< Y > &a_rhs)
Definition hkRefPtr.h:101
hkRefPtr & operator=(hkRefPtr &&a_rhs)
Definition hkRefPtr.h:110
Definition AbsorbEffect.h:6
constexpr bool operator==(const BSTSmartPointer< T1 > &a_lhs, const BSTSmartPointer< T2 > &a_rhs)
Definition BSTSmartPointer.h:240
hkRefPtr< T > make_hkref(Args &&... a_args)
Definition hkRefPtr.h:204
constexpr bool operator!=(const BSTSmartPointer< T1 > &a_lhs, const BSTSmartPointer< T2 > &a_rhs)
Definition BSTSmartPointer.h:246