CommonLibSSE (Parapets fork)
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 };
25 static_assert(sizeof(NiRTTI) == 0x10);
26
27 namespace Ni_Impl
28 {
29 template <class T>
31 std::remove_pointer_t<
32 std::remove_reference_t<
33 std::remove_cv_t<T>>>;
34
35 template <class To, class From>
37 std::false_type
38 {};
39
40 template <class To, class From>
41 struct types_are_compat<To&, From> :
42 std::is_lvalue_reference<
43 std::remove_cv_t<From>>
44 {};
45
46 template <class To, class From>
47 struct types_are_compat<To*, From> :
48 std::is_pointer<
49 std::remove_cv_t<From>>
50 {};
51
52 template <class Base, class Derived>
54 std::is_base_of<
55 remove_cvpr_t<Base>,
56 remove_cvpr_t<Derived>>
57 {};
58
59 template <class T, class Enable = void>
60 struct _has_rtti :
61 std::false_type
62 {};
63
64 template <class T>
65 struct _has_rtti<T, std::void_t<decltype(T::Ni_RTTI)>> :
66 std::true_type
67 {};
68
69 template <class T>
70 struct has_rtti :
71 _has_rtti<remove_cvpr_t<T>>
72 {};
73
74 template <class To, class From>
76 std::conjunction<
77 types_are_compat<To, From>,
78 is_base_of_no_cvpr<From, To>,
79 has_rtti<To>,
80 has_rtti<From>>
81 {};
82
83 template <class To, class From>
85 }
86}
87
88// downcast
89template <
90 class To,
91 class From,
92 std::enable_if_t<
94 To,
95 const From*>,
96 int> = 0>
97To netimmerse_cast(const From* a_from)
98{
99 if (!a_from) {
100 return nullptr;
101 }
102
104
105 const RE::NiRTTI* toRTTI = to.get();
106 const RE::NiRTTI* fromRTTI = a_from->GetRTTI();
107 while (fromRTTI) {
108 if (fromRTTI == toRTTI) {
109 return static_cast<To>(const_cast<From*>(a_from));
110 }
111 fromRTTI = fromRTTI->GetBaseRTTI();
112 }
113
114 return nullptr;
115}
116
117// upcast
118template <
119 class To,
120 class From,
121 std::enable_if_t<
123 const From*,
124 To>,
125 int> = 0>
126To netimmerse_cast(const From* a_from)
127{
128 return static_cast<To>(const_cast<From*>(a_from));
129}
To netimmerse_cast(const From *a_from)
Definition: NiRTTI.h:97
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: Relocation.h:858
std::remove_pointer_t< std::remove_reference_t< std::remove_cv_t< T > > > remove_cvpr_t
Definition: NiRTTI.h:33
constexpr bool cast_is_valid_v
Definition: NiRTTI.h:84
Definition: AbsorbEffect.h:6
Definition: NiBinaryStream.h:94
Definition: NiRTTI.h:62
Definition: NiRTTI.h:81
Definition: NiRTTI.h:72
Definition: NiRTTI.h:57
Definition: NiRTTI.h:38