CommonLibSSE (powerof3)
PackUnpack.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "RE/B/BSTSmartPointer.h"
4 #include "RE/R/ReferenceArray.h"
5 #include "RE/T/TypeTraits.h"
6 #include "RE/V/Variable.h"
7 
8 namespace RE
9 {
10  namespace BSScript
11  {
12  class Object;
13 
15  void BindID(BSTSmartPointer<Object>& a_object, const void* a_src, VMTypeID a_typeID);
16  void PackHandle(Variable* a_dst, const void* a_src, VMTypeID a_typeID);
17  void* UnpackHandle(const Variable* a_src, VMTypeID a_typeID);
18 
19  template <
20  class T,
21  std::enable_if_t<
22  is_builtin_convertible_v<T>,
23  int> = 0>
24  [[nodiscard]] inline TypeInfo::RawType GetRawType()
25  {
26  return vm_type_v<T>;
27  }
28 
29  template <
30  class T,
31  std::enable_if_t<
32  is_form_pointer_v<T>,
33  int> = 0>
34  [[nodiscard]] inline TypeInfo::RawType GetRawType()
35  {
36  return GetRawTypeFromVMType(static_cast<VMTypeID>(decay_pointer_t<T>::FORMTYPE));
37  }
38 
39  template <
40  class T,
41  std::enable_if_t<
42  is_alias_pointer_v<T>,
43  int> = 0>
44  [[nodiscard]] inline TypeInfo::RawType GetRawType()
45  {
46  return GetRawTypeFromVMType(decay_pointer_t<T>::VMTYPEID);
47  }
48 
49  template <
50  class T,
51  std::enable_if_t<
52  is_active_effect_pointer_v<T>,
53  int> = 0>
54  [[nodiscard]] inline TypeInfo::RawType GetRawType()
55  {
56  return GetRawTypeFromVMType(decay_pointer_t<T>::VMTYPEID);
57  }
58 
59  template <
60  class T,
61  std::enable_if_t<
62  std::disjunction_v<
63  is_array<T>,
64  is_reference_wrapper<T>>,
65  int> = 0>
66  [[nodiscard]] inline TypeInfo::RawType GetRawType()
67  {
68  using value_type = typename T::value_type;
69  if constexpr (is_builtin_convertible_v<value_type>) {
70  return *(REX::EnumSet{ vm_type_v<T> } + TypeInfo::RawType::kNoneArray);
71  } else if constexpr (is_form_pointer_v<value_type>) {
72  return *(REX::EnumSet{ GetRawTypeFromVMType(static_cast<VMTypeID>(unwrapped_type_t<T>::FORMTYPE)) } + TypeInfo::RawType::kObject);
73  } else if constexpr (is_alias_pointer_v<value_type> || is_active_effect_pointer_v<value_type>) {
74  return *(REX::EnumSet{ GetRawTypeFromVMType(static_cast<VMTypeID>(unwrapped_type_t<T>::VMTYPEID)) } + TypeInfo::RawType::kObject);
75  } else {
76  static_assert(sizeof(T) && false);
77  }
78  }
79 
80  template <
81  class T,
82  class U = std::decay_t<T>,
83  std::enable_if_t<
84  is_string_convertible_v<U>,
85  int> = 0>
86  inline void PackValue(Variable* a_dst, T&& a_src)
87  {
88  assert(a_dst);
89  a_dst->SetString(std::forward<T>(a_src));
90  }
91 
92  template <class T,
93  class U = std::decay_t<T>,
94  std::enable_if_t<
95  is_signed_integral_convertible_v<U>,
96  int> = 0>
97  inline void PackValue(Variable* a_dst, T&& a_src)
98  {
99  assert(a_dst);
100  a_dst->SetSInt(static_cast<std::int32_t>(std::forward<T>(a_src)));
101  }
102 
103  template <class T,
104  class U = std::decay_t<T>,
105  std::enable_if_t<
106  is_unsigned_integral_convertible_v<U>,
107  int> = 0>
108  inline void PackValue(Variable* a_dst, T&& a_src)
109  {
110  assert(a_dst);
111  a_dst->SetUInt(static_cast<std::uint32_t>(std::forward<T>(a_src)));
112  }
113 
114  template <
115  class T,
116  class U = std::decay_t<T>,
117  std::enable_if_t<
118  is_floating_point_convertible_v<U>,
119  int> = 0>
120  inline void PackValue(Variable* a_dst, T&& a_src)
121  {
122  assert(a_dst);
123  a_dst->SetFloat(static_cast<float>(std::forward<T>(a_src)));
124  }
125 
126  template <
127  class T,
128  class U = std::decay_t<T>,
129  std::enable_if_t<
130  is_boolean_v<U>,
131  int> = 0>
132  inline void PackValue(Variable* a_dst, T&& a_src)
133  {
134  assert(a_dst);
135  a_dst->SetBool(static_cast<bool>(std::forward<T>(a_src)));
136  }
137 
138  template <
139  class T,
140  class U = std::decay_t<T>,
141  std::enable_if_t<
142  is_form_pointer_v<U>,
143  int> = 0>
144  inline void PackValue(Variable* a_dst, T&& a_src)
145  {
146  PackHandle(a_dst, std::forward<T>(a_src), static_cast<VMTypeID>(decay_pointer_t<U>::FORMTYPE));
147  }
148 
149  template <
150  class T,
151  class U = std::decay_t<T>,
152  std::enable_if_t<
153  is_alias_pointer_v<U>,
154  int> = 0>
155  inline void PackValue(Variable* a_dst, T&& a_src)
156  {
157  PackHandle(a_dst, std::forward<T>(a_src), decay_pointer_t<U>::VMTYPEID);
158  }
159 
160  template <
161  class T,
162  class U = std::decay_t<T>,
163  std::enable_if_t<
164  is_active_effect_pointer_v<U>,
165  int> = 0>
166  inline void PackValue(Variable* a_dst, T&& a_src)
167  {
168  PackHandle(a_dst, std::forward<T>(a_src), decay_pointer_t<U>::VMTYPEID);
169  }
170 
171  template <
172  class T,
173  class U = std::decay_t<T>,
174  std::enable_if_t<
175  is_array_v<U>,
176  int> = 0>
177  void PackValue(Variable* a_dst, T&& a_src);
178 
179  template <
180  class T,
181  std::enable_if_t<
182  is_static_base_pointer_v<T>,
183  int> = 0>
184  [[nodiscard]] inline T UnpackValue([[maybe_unused]] const Variable* a_src)
185  {
186  return static_cast<T>(nullptr);
187  }
188 
189  template <
190  class T,
191  std::enable_if_t<
192  is_string_convertible_v<T>,
193  int> = 0>
194  [[nodiscard]] inline T UnpackValue(const Variable* a_src)
195  {
196  assert(a_src);
197  return T{ a_src->GetString() };
198  }
199 
200  template <
201  class T,
202  std::enable_if_t<
203  is_signed_integral_convertible_v<T>,
204  int> = 0>
205  [[nodiscard]] inline T UnpackValue(const Variable* a_src)
206  {
207  assert(a_src);
208  return static_cast<T>(a_src->GetSInt());
209  }
210 
211  template <
212  class T,
213  std::enable_if_t<
214  is_unsigned_integral_convertible_v<T>,
215  int> = 0>
216  [[nodiscard]] inline T UnpackValue(const Variable* a_src)
217  {
218  assert(a_src);
219  return static_cast<T>(a_src->GetUInt());
220  }
221 
222  template <
223  class T,
224  std::enable_if_t<
225  is_floating_point_convertible_v<T>,
226  int> = 0>
227  [[nodiscard]] inline T UnpackValue(const Variable* a_src)
228  {
229  assert(a_src);
230  return static_cast<T>(a_src->GetFloat());
231  }
232 
233  template <
234  class T,
235  std::enable_if_t<
236  is_boolean_v<T>,
237  int> = 0>
238  [[nodiscard]] inline T UnpackValue(const Variable* a_src)
239  {
240  assert(a_src);
241  return static_cast<T>(a_src->GetBool());
242  }
243 
244  template <
245  class T,
246  std::enable_if_t<
247  is_form_pointer_v<T>,
248  int> = 0>
249  [[nodiscard]] inline T UnpackValue(const Variable* a_src)
250  {
251  return static_cast<T>(UnpackHandle(a_src, static_cast<VMTypeID>(decay_pointer_t<T>::FORMTYPE)));
252  }
253 
254  template <
255  class T,
256  std::enable_if_t<
257  is_alias_pointer_v<T>,
258  int> = 0>
259  [[nodiscard]] inline T UnpackValue(const Variable* a_src)
260  {
261  return static_cast<T>(UnpackHandle(a_src, decay_pointer_t<T>::VMTYPEID));
262  }
263 
264  template <
265  class T,
266  std::enable_if_t<
267  is_active_effect_pointer_v<T>,
268  int> = 0>
269  [[nodiscard]] inline T UnpackValue(const Variable* a_src)
270  {
271  return static_cast<T>(UnpackHandle(a_src, decay_pointer_t<T>::VMTYPEID));
272  }
273 
274  template <
275  class T,
276  std::enable_if_t<
277  is_array_v<T>,
278  int> = 0>
279  [[nodiscard]] T UnpackValue(const Variable* a_src);
280 
281  template <
282  class T,
283  std::enable_if_t<
284  is_reference_wrapper_v<T>,
285  int> = 0>
286  inline T UnpackValue(const Variable* a_src)
287  {
288  return T{ a_src };
289  }
290 
291  template <class T>
292  inline void Variable::Pack(T&& a_src)
293  {
294  PackValue<T>(this, std::forward<T>(a_src));
295  }
296 
297  template <class T>
298  [[nodiscard]] inline T Variable::Unpack() const
299  {
300  return UnpackValue<T>(this);
301  }
302  }
303 }
Definition: EnumSet.h:9
RawType
Definition: TypeInfo.h:13
Definition: Variable.h:15
void SetString(std::string_view a_val)
void Pack(T &&a_src)
Definition: PackUnpack.h:292
T Unpack() const
Definition: PackUnpack.h:298
std::string_view GetString() const
Definition: BSTSmartPointer.h:37
T UnpackValue([[maybe_unused]] const Variable *a_src)
Definition: PackUnpack.h:184
TypeInfo::RawType GetRawTypeFromVMType(VMTypeID a_typeID)
void PackHandle(Variable *a_dst, const void *a_src, VMTypeID a_typeID)
TypeInfo::RawType GetRawType()
Definition: PackUnpack.h:24
void * UnpackHandle(const Variable *a_src, VMTypeID a_typeID)
void PackValue(Variable *a_dst, T &&a_src)
Definition: PackUnpack.h:86
void BindID(BSTSmartPointer< Object > &a_object, const void *a_src, VMTypeID a_typeID)
Definition: AbsorbEffect.h:6
std::uint32_t VMTypeID
Definition: BSCoreTypes.h:9