54 constexpr typename std::enable_if<std::is_polymorphic<t_type>::value,
bool>
::type CheckCanCast(t_type* other)
73 template<
class>
friend class Pointer;
78 Pointer(t_type* value) noexcept
79 : m_core(value ==
nullptr ?
nullptr :
new PointerCore())
82 template<
class t_parent_type>
83 Pointer(t_parent_type* value) noexcept
84 : m_core(value ==
nullptr ?
nullptr :
new PointerCore())
87 Pointer(
const Pointer<t_type>& value) noexcept
88 : m_core(value.m_core)
89 , m_object(value.m_object)
91 if (m_core !=
nullptr)
94 Pointer(Pointer<t_type>&& value) noexcept
98 std::swap(m_core, value.m_core);
99 std::swap(m_object, value.m_object);
101 Pointer(t_type&& value) noexcept
103 , m_object(
new t_type(std::move(value)))
106 template<
class t_parent_type, std::enable_if_t<std::is_base_of_v<t_type, t_parent_type>,
int> = 0>
107 Pointer(t_parent_type&& value) noexcept
109 , m_object(
new t_parent_type(std::move(value)))
111 template<
class t_parent_type, std::enable_if_t<std::is_base_of_v<t_type, t_parent_type>,
int> = 0>
112 Pointer(Pointer<t_parent_type>&& value) noexcept
116 std::swap(m_core, value.m_core);
117 m_object = value.m_object;
118 value.m_object =
nullptr;
122 lib_assert(m_object !=
nullptr,
"Tried to access null pointer");
125 constexpr t_type* rawptr()
const
129 void set(t_type&& value)
133 m_object =
new t_type(std::move(value));
135 Pointer& operator=(
const Pointer& pointer)
137 if (pointer.m_core == m_core)
140 m_core = pointer.m_core;
141 m_object = pointer.m_object;
144 lib_assert((m_core ==
nullptr) == (m_object ==
nullptr),
"Pointer core null mismatch");
147 Pointer& operator=(t_type* pointer)
155 lib_assert((m_core ==
nullptr) == (m_object ==
nullptr),
"Pointer core null mismatch");
164 bool isNull()
const {
return m_object ==
nullptr; }
167 if (m_core ==
nullptr)
170 if (m_core->reference_count == 0)
178 [[nodiscard]]
uint04 referenceCount()
const
181 return m_core->reference_count;
185 bool operator==(
const Pointer<t_type>& pointer)
const
187 return pointer.m_object == m_object;
189 bool operator!=(
const Pointer<t_type>& pointer)
const
191 return pointer.m_object != m_object;
193 void swap(Pointer<t_type>& pointer)
195 std::swap(m_core, pointer.m_core);
196 std::swap(m_object, pointer.m_object);
200 t_type* m_object =
nullptr;
275 class ConstPointer :
public Pointer<t_type>
280 ConstPointer(
const t_type* value) noexcept
281 : Pointer<t_type>(
const_cast<t_type*
>(value))
283 template<
class t_parent_type>
284 ConstPointer(t_parent_type* value) noexcept
285 : Pointer<t_type>(value)
287 ConstPointer(
const Pointer<t_type>& value) noexcept
288 : Pointer<t_type>(value)
290 ConstPointer(t_type&& value) noexcept
291 : Pointer<t_type>(std::move(value))
293 ConstPointer(Pointer<t_type>&& value) noexcept
294 : Pointer<t_type>(std::move(value))
296 template<
class t_parent_type, std::enable_if_t<std::is_base_of_v<t_type, t_parent_type>,
int> = 0>
297 ConstPointer(t_parent_type&& value) noexcept
298 : Pointer<t_type>(std::move(value))
300 template<
class t_parent_type, std::enable_if_t<std::is_base_of_v<t_type, t_parent_type>,
int> = 0>
301 ConstPointer(Pointer<t_parent_type>&& value) noexcept
302 : Pointer<t_type>(std::move(value))
304 const t_type& get()
const
306 lib_assert(!Pointer<t_type>::isNull(),
"Tried to access nullptr");
307 return Pointer<t_type>::get();
309 constexpr const t_type* rawptr()
const
311 return Pointer<t_type>::rawptr();
313 void set(t_type&& value)
noexcept
315 Pointer<t_type>::set(std::move(value));
317 const t_type* operator->()
const
319 lib_assert(!Pointer<t_type>::isNull(),
"Tried to access nullptr");
320 return &Pointer<t_type>::get();
323 ConstPointer<t_type>& operator=(
const Pointer<t_type>& pointer)
noexcept
325 Pointer<t_type>::operator=(pointer);
328 ConstPointer<t_type>& operator=(t_type* pointer)
330 Pointer<t_type>::operator=(pointer);
333 template<
class t_other_type>
334 ConstPointer<t_other_type> as()
const
336 ConstPointer<t_other_type> pointer;
337#ifndef NDEVR_USE_STD_POINTER
338 if (Pointer<t_type>::m_core && CheckCanCast<t_other_type>(Pointer<t_type>::m_object))
340 memcpy(&pointer,
this,
sizeof(ConstPointer<t_type>));
344 pointer.m_ptr = std::dynamic_pointer_cast<t_other_type>(Pointer<t_type>::m_ptr);
355 class DynamicPointer :
public ConstPointer<t_type>
360 DynamicPointer(t_type* value) noexcept
361 : ConstPointer<t_type>(value)
363 template<
class t_parent_type>
364 DynamicPointer(t_parent_type* value) noexcept
365 : ConstPointer<t_type>(value)
367 DynamicPointer(t_type&& value) noexcept
368 : ConstPointer<t_type>(std::move(value))
370 DynamicPointer(
const DynamicPointer<t_type>& value) noexcept
371 : ConstPointer<t_type>(value)
373 DynamicPointer(DynamicPointer<t_type>&& value) noexcept
374 : ConstPointer<t_type>(std::move(value))
376 template<
class t_parent_type, std::enable_if_t<std::is_base_of_v<t_type, t_parent_type>,
int> = 0>
377 DynamicPointer(t_parent_type&& value) noexcept
378 : ConstPointer<t_type>(std::move(value))
380 template<
class t_parent_type, std::enable_if_t<std::is_base_of_v<t_type, t_parent_type>,
int> = 0>
381 DynamicPointer(DynamicPointer<t_parent_type>&& value) noexcept
382 : ConstPointer<t_type>(std::move(value))
385 constexpr t_type& get()
const
387 return Pointer<t_type>::get();
389 constexpr t_type* rawptr()
const
391 return Pointer<t_type>::rawptr();
394 void set(t_type&& value)
396 Pointer<t_type>::set(std::move(value));
398 t_type* operator->()
const
400 lib_assert(!Pointer<t_type>::isNull(),
"Tried to access nullptr");
401 return &Pointer<t_type>::get();
404 DynamicPointer& operator=(
const DynamicPointer& pointer)
406 Pointer<t_type>::operator=(pointer);
409 DynamicPointer& operator=(t_type* pointer)
411 Pointer<t_type>::operator=(pointer);
415 template<
class t_other_type>
416 DynamicPointer<t_other_type> as()
const
418 DynamicPointer<t_other_type> pointer;
419#ifndef NDEVR_USE_STD_POINTER
420 if (Pointer<t_type>::m_core && CheckCanCast<t_other_type>(Pointer<t_type>::m_object))
422 memcpy(&pointer,
this,
sizeof(DynamicPointer<t_type>));