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