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