CommonLibVR
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  private:
25  KEEP_FOR_RE()
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>
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>
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>
87  }
88 }
89 
90 // downcast
91 template <
92  class To,
93  class From,
94  std::enable_if_t<
96  To,
97  const From*>,
98  int> = 0>
99 To netimmerse_cast(const From* a_from)
100 {
101  if (!a_from) {
102  return nullptr;
103  }
104 
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
120 template <
121  class To,
122  class From,
123  std::enable_if_t<
125  const From*,
126  To>,
127  int> = 0>
128 To 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:713
Definition: Relocation.h:210
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:35
constexpr bool cast_is_valid_v
Definition: NiRTTI.h:86
Definition: AbsorbEffect.h:6
Definition: EffectArchetypes.h:65
Definition: NiRTTI.h:64
Definition: NiRTTI.h:83
Definition: NiRTTI.h:74
Definition: NiRTTI.h:59
Definition: NiRTTI.h:40