CommonLibVR
Loading...
Searching...
No Matches
NiRTTI.h
Go to the documentation of this file.
1#pragma once
2
3namespace RE
4{
5 class NiRTTI
6 {
7 public:
8 [[nodiscard]] constexpr const char* GetName() const noexcept { return name; }
9 [[nodiscard]] constexpr const NiRTTI* GetBaseRTTI() const noexcept { return baseRTTI; }
10
11 [[nodiscard]] constexpr bool IsKindOf(const NiRTTI* a_rtti) const noexcept
12 {
13 for (auto iter = this; iter; iter = iter->GetBaseRTTI()) {
14 if (iter == a_rtti) {
15 return true;
16 }
17 }
18 return false;
19 }
20
21 // members
22 const char* name; // 00
23 const NiRTTI* baseRTTI; // 08
24 private:
26 };
27 static_assert(sizeof(NiRTTI) == 0x10);
28
29 namespace Ni_Impl
30 {
31 template <class T>
32 using remove_cvpr_t =
33 std::remove_pointer_t<
34 std::remove_reference_t<
35 std::remove_cv_t<T>>>;
36
37 template <class To, class From>
38 struct types_are_compat :
39 std::false_type
40 {};
41
42 template <class To, class From>
43 struct types_are_compat<To&, From> :
44 std::is_lvalue_reference<
45 std::remove_cv_t<From>>
46 {};
47
48 template <class To, class From>
49 struct types_are_compat<To*, From> :
50 std::is_pointer<
51 std::remove_cv_t<From>>
52 {};
53
54 template <class Base, class Derived>
55 struct is_base_of_no_cvpr :
56 std::is_base_of<
57 remove_cvpr_t<Base>,
58 remove_cvpr_t<Derived>>
59 {};
60
61 template <class T, class Enable = void>
62 struct _has_rtti :
63 std::false_type
64 {};
65
66 template <class T>
67 struct _has_rtti<T, std::void_t<decltype(T::Ni_RTTI)>> :
68 std::true_type
69 {};
70
71 template <class T>
72 struct has_rtti :
73 _has_rtti<remove_cvpr_t<T>>
74 {};
75
76 template <class To, class From>
77 struct cast_is_valid :
78 std::conjunction<
79 types_are_compat<To, From>,
80 is_base_of_no_cvpr<From, To>,
81 has_rtti<To>,
82 has_rtti<From>>
83 {};
84
85 template <class To, class From>
86 inline constexpr bool cast_is_valid_v = cast_is_valid<To, From>::value;
87 }
88}
89
90// downcast
91template <
92 class To,
93 class From,
94 std::enable_if_t<
95 RE::Ni_Impl::cast_is_valid_v<
96 To,
97 const From*>,
98 int> = 0>
99To netimmerse_cast(const From* a_from)
100{
101 if (!a_from) {
102 return nullptr;
103 }
104
105 static REL::Relocation<const RE::NiRTTI*> to{ RE::Ni_Impl::remove_cvpr_t<To>::Ni_RTTI };
106
107 const RE::NiRTTI* toRTTI = to.get();
108 const RE::NiRTTI* fromRTTI = a_from->GetRTTI();
109 while (fromRTTI) {
110 if (fromRTTI == toRTTI) {
111 return static_cast<To>(const_cast<From*>(a_from));
112 }
113 fromRTTI = fromRTTI->GetBaseRTTI();
114 }
115
116 return nullptr;
117}
118
119// upcast
120template <
121 class To,
122 class From,
123 std::enable_if_t<
124 RE::Ni_Impl::cast_is_valid_v<
125 const From*,
126 To>,
127 int> = 0>
128To netimmerse_cast(const From* a_from)
129{
130 return static_cast<To>(const_cast<From*>(a_from));
131}
To netimmerse_cast(const From *a_from)
Definition NiRTTI.h:99
#define KEEP_FOR_RE()
Definition PCH.h:517
Definition Relocation.h:210
Definition NiRTTI.h:6
constexpr bool IsKindOf(const NiRTTI *a_rtti) const noexcept
Definition NiRTTI.h:11
constexpr const NiRTTI * GetBaseRTTI() const noexcept
Definition NiRTTI.h:9
const NiRTTI * baseRTTI
Definition NiRTTI.h:23
constexpr const char * GetName() const noexcept
Definition NiRTTI.h:8
const char * name
Definition NiRTTI.h:22
Definition AbsorbEffect.h:6
Definition EffectArchetypes.h:65