CommonLibSSE (powerof3)
NiRTTI.h
Go to the documentation of this file.
1 #pragma once
2 
3 namespace 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>
30  using remove_cvpr_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>
75  struct cast_is_valid :
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
89 template <
90  class To,
91  class From,
92  std::enable_if_t<
94  To,
95  const From*>,
96  int> = 0>
97 To 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
118 template <
119  class To,
120  class From,
121  std::enable_if_t<
123  const From*,
124  To>,
125  int> = 0>
126 To 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: Relocation.h:867
Definition: NiRTTI.h:6
constexpr bool IsKindOf(const NiRTTI *a_rtti) const noexcept
Definition: NiRTTI.h:11
const NiRTTI * baseRTTI
Definition: NiRTTI.h:23
constexpr const char * GetName() const noexcept
Definition: NiRTTI.h:8
constexpr const NiRTTI * GetBaseRTTI() const noexcept
Definition: NiRTTI.h:9
const char * name
Definition: NiRTTI.h:22
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