CommonLibSSE (Parapets fork)
PCH.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <array>
5 #include <bit>
6 #include <bitset>
7 #include <cassert>
8 #include <cmath>
9 #include <concepts>
10 #include <coroutine>
11 #include <cstdarg>
12 #include <cstddef>
13 #include <cstdint>
14 #include <cstdio>
15 #include <cstdlib>
16 #include <cstring>
17 #include <ctime>
18 #include <cwchar>
19 #include <cwctype>
20 #include <exception>
21 #include <execution>
22 #include <filesystem>
23 #include <fstream>
24 #include <functional>
25 #include <iomanip>
26 #include <ios>
27 #include <istream>
28 #include <iterator>
29 #include <limits>
30 #include <locale>
31 #include <map>
32 #include <memory>
33 #include <mutex>
34 #include <new>
35 #include <numeric>
36 #include <optional>
37 #include <regex>
38 #include <set>
39 #include <source_location>
40 #include <span>
41 #include <sstream>
42 #include <stack>
43 #include <stdexcept>
44 #include <string>
45 #include <string_view>
46 #include <system_error>
47 #include <thread>
48 #include <tuple>
49 #include <type_traits>
50 #include <typeinfo>
51 #include <utility>
52 #include <variant>
53 #include <vector>
54 
55 static_assert(
56  std::is_integral_v<std::time_t> && sizeof(std::time_t) == sizeof(std::size_t),
57  "wrap std::time_t instead");
58 
59 #pragma warning(push)
60 #include <binary_io/file_stream.hpp>
61 #include <boost/stl_interfaces/iterator_interface.hpp>
62 #include <fmt/format.h>
63 #include <spdlog/spdlog.h>
64 #pragma warning(pop)
65 
66 #include "SKSE/Impl/WinAPI.h"
67 
68 namespace SKSE
69 {
70  using namespace std::literals;
71 
72  namespace stl
73  {
74  template <class CharT>
75  using basic_zstring = std::basic_string_view<CharT>;
76 
79 
80  // owning pointer
81  template <
82  class T,
83  class = std::enable_if_t<
84  std::is_pointer_v<T>>>
85  using owner = T;
86 
87  // non-owning pointer
88  template <
89  class T,
90  class = std::enable_if_t<
91  std::is_pointer_v<T>>>
92  using observer = T;
93 
94  // non-null pointer
95  template <
96  class T,
97  class = std::enable_if_t<
98  std::is_pointer_v<T>>>
99  using not_null = T;
100 
101  namespace nttp
102  {
103  template <class CharT, std::size_t N>
104  struct string
105  {
106  using char_type = CharT;
107  using pointer = char_type*;
108  using const_pointer = const char_type*;
110  using const_reference = const char_type&;
111  using size_type = std::size_t;
112 
113  static constexpr auto npos = static_cast<std::size_t>(-1);
114 
115  consteval string(const_pointer a_string) noexcept
116  {
117  for (size_type i = 0; i < N; ++i) {
118  c[i] = a_string[i];
119  }
120  }
121 
122  [[nodiscard]] consteval const_reference operator[](size_type a_pos) const noexcept
123  {
124  assert(a_pos < N);
125  return c[a_pos];
126  }
127 
128  [[nodiscard]] consteval const_reference back() const noexcept { return (*this)[size() - 1]; }
129  [[nodiscard]] consteval const_pointer data() const noexcept { return c; }
130  [[nodiscard]] consteval bool empty() const noexcept { return this->size() == 0; }
131  [[nodiscard]] consteval const_reference front() const noexcept { return (*this)[0]; }
132  [[nodiscard]] consteval size_type length() const noexcept { return N; }
133  [[nodiscard]] consteval size_type size() const noexcept { return length(); }
134 
135  template <std::size_t POS = 0, std::size_t COUNT = npos>
136  [[nodiscard]] consteval auto substr() const noexcept
137  {
138  return string < CharT, COUNT != npos ? COUNT : N - POS > (this->data() + POS);
139  }
140 
141  char_type c[N] = {};
142  };
143 
144  template <class CharT, std::size_t N>
145  string(const CharT (&)[N]) -> string<CharT, N - 1>;
146 
147  template <class CharT, std::size_t N>
148  struct zstring
149  {
150  using char_type = CharT;
151  using pointer = char_type*;
152  using const_pointer = const char_type*;
154  using const_reference = const char_type&;
155  using size_type = std::size_t;
156 
157  static constexpr auto npos = static_cast<std::size_t>(-1);
158 
159  consteval zstring(const char_type (&a_string)[N]) noexcept
160  {
161  for (size_type i = 0; i < N; ++i) {
162  c[i] = a_string[i];
163  }
164  }
165 
166  [[nodiscard]] consteval const_reference operator[](size_type a_pos) const noexcept
167  {
168  assert(a_pos < N);
169  return c[a_pos];
170  }
171 
172  [[nodiscard]] consteval const_reference back() const noexcept { return (*this)[size() - 1]; }
173  [[nodiscard]] consteval const_pointer data() const noexcept { return c; }
174  [[nodiscard]] consteval bool empty() const noexcept { return this->size() == 0; }
175  [[nodiscard]] consteval const_reference front() const noexcept { return (*this)[0]; }
176  [[nodiscard]] consteval size_type length() const noexcept { return N - 1; }
177  [[nodiscard]] consteval size_type size() const noexcept { return length(); }
178 
179  template <std::size_t POS = 0, std::size_t COUNT = npos>
180  [[nodiscard]] consteval auto substr() const noexcept
181  {
182  return string < CharT, COUNT != npos ? COUNT : N - 1 - POS > (this->data() + POS);
183  }
184 
185  char_type c[N] = {};
186  };
187  }
188 
189  template <class EF> //
190  requires(std::invocable<std::remove_reference_t<EF>>) //
191  class scope_exit
192  {
193  public:
194  // 1)
195  template <class Fn>
196  explicit scope_exit(Fn&& a_fn) //
197  noexcept(std::is_nothrow_constructible_v<EF, Fn> ||
198  std::is_nothrow_constructible_v<EF, Fn&>) //
199  requires(!std::is_same_v<std::remove_cvref_t<Fn>, scope_exit> &&
200  std::is_constructible_v<EF, Fn>)
201  {
202  static_assert(std::invocable<Fn>);
203 
204  if constexpr (!std::is_lvalue_reference_v<Fn> &&
205  std::is_nothrow_constructible_v<EF, Fn>) {
206  _fn.emplace(std::forward<Fn>(a_fn));
207  } else {
208  _fn.emplace(a_fn);
209  }
210  }
211 
212  // 2)
213  scope_exit(scope_exit&& a_rhs) //
214  noexcept(std::is_nothrow_move_constructible_v<EF> ||
215  std::is_nothrow_copy_constructible_v<EF>) //
216  requires(std::is_nothrow_move_constructible_v<EF> ||
217  std::is_copy_constructible_v<EF>)
218  {
219  static_assert(!(std::is_nothrow_move_constructible_v<EF> && !std::is_move_constructible_v<EF>));
220  static_assert(!(!std::is_nothrow_move_constructible_v<EF> && !std::is_copy_constructible_v<EF>));
221 
222  if (a_rhs.active()) {
223  if constexpr (std::is_nothrow_move_constructible_v<EF>) {
224  _fn.emplace(std::forward<EF>(*a_rhs._fn));
225  } else {
226  _fn.emplace(a_rhs._fn);
227  }
228  a_rhs.release();
229  }
230  }
231 
232  // 3)
233  scope_exit(const scope_exit&) = delete;
234 
235  ~scope_exit() noexcept
236  {
237  if (_fn.has_value()) {
238  (*_fn)();
239  }
240  }
241 
242  void release() noexcept { _fn.reset(); }
243 
244  private:
245  [[nodiscard]] bool active() const noexcept { return _fn.has_value(); }
246 
247  std::optional<std::remove_reference_t<EF>> _fn;
248  };
249 
250  template <class EF>
251  scope_exit(EF) -> scope_exit<EF>;
252 
253  template <
254  class Enum,
255  class Underlying = std::underlying_type_t<Enum>>
257  {
258  public:
259  using enum_type = Enum;
260  using underlying_type = Underlying;
261 
262  static_assert(std::is_enum_v<enum_type>, "enum_type must be an enum");
263  static_assert(std::is_integral_v<underlying_type>, "underlying_type must be an integral");
264 
265  constexpr enumeration() noexcept = default;
266 
267  constexpr enumeration(const enumeration&) noexcept = default;
268 
269  constexpr enumeration(enumeration&&) noexcept = default;
270 
271  template <class U2> // NOLINTNEXTLINE(google-explicit-constructor)
272  constexpr enumeration(enumeration<Enum, U2> a_rhs) noexcept :
273  _impl(static_cast<underlying_type>(a_rhs.get()))
274  {}
275 
276  template <class... Args>
277  constexpr enumeration(Args... a_values) noexcept //
278  requires(std::same_as<Args, enum_type>&&...) :
279  _impl((static_cast<underlying_type>(a_values) | ...))
280  {}
281 
282  ~enumeration() noexcept = default;
283 
284  constexpr enumeration& operator=(const enumeration&) noexcept = default;
285  constexpr enumeration& operator=(enumeration&&) noexcept = default;
286 
287  template <class U2>
288  constexpr enumeration& operator=(enumeration<Enum, U2> a_rhs) noexcept
289  {
290  _impl = static_cast<underlying_type>(a_rhs.get());
291  }
292 
293  constexpr enumeration& operator=(enum_type a_value) noexcept
294  {
295  _impl = static_cast<underlying_type>(a_value);
296  return *this;
297  }
298 
299  [[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast<underlying_type>(0); }
300 
301  [[nodiscard]] constexpr enum_type operator*() const noexcept { return get(); }
302  [[nodiscard]] constexpr enum_type get() const noexcept { return static_cast<enum_type>(_impl); }
303  [[nodiscard]] constexpr underlying_type underlying() const noexcept { return _impl; }
304 
305  template <class... Args>
306  constexpr enumeration& set(Args... a_args) noexcept //
307  requires(std::same_as<Args, enum_type>&&...)
308  {
309  _impl |= (static_cast<underlying_type>(a_args) | ...);
310  return *this;
311  }
312 
313  template <class... Args>
314  constexpr enumeration& reset(Args... a_args) noexcept //
315  requires(std::same_as<Args, enum_type>&&...)
316  {
317  _impl &= ~(static_cast<underlying_type>(a_args) | ...);
318  return *this;
319  }
320 
321  template <class... Args>
322  [[nodiscard]] constexpr bool any(Args... a_args) const noexcept //
323  requires(std::same_as<Args, enum_type>&&...)
324  {
325  return (_impl & (static_cast<underlying_type>(a_args) | ...)) != static_cast<underlying_type>(0);
326  }
327 
328  template <class... Args>
329  [[nodiscard]] constexpr bool all(Args... a_args) const noexcept //
330  requires(std::same_as<Args, enum_type>&&...)
331  {
332  return (_impl & (static_cast<underlying_type>(a_args) | ...)) == (static_cast<underlying_type>(a_args) | ...);
333  }
334 
335  template <class... Args>
336  [[nodiscard]] constexpr bool none(Args... a_args) const noexcept //
337  requires(std::same_as<Args, enum_type>&&...)
338  {
339  return (_impl & (static_cast<underlying_type>(a_args) | ...)) == static_cast<underlying_type>(0);
340  }
341 
342  private:
343  underlying_type _impl{ 0 };
344  };
345 
346  template <class... Args>
348  std::common_type_t<Args...>,
349  std::underlying_type_t<
350  std::common_type_t<Args...>>>;
351  }
352 }
353 
354 #define SKSE_MAKE_LOGICAL_OP(a_op, a_result) \
355  template <class E, class U1, class U2> \
356  [[nodiscard]] constexpr a_result operator a_op(enumeration<E, U1> a_lhs, enumeration<E, U2> a_rhs) noexcept \
357  { \
358  return a_lhs.get() a_op a_rhs.get(); \
359  } \
360  \
361  template <class E, class U> \
362  [[nodiscard]] constexpr a_result operator a_op(enumeration<E, U> a_lhs, E a_rhs) noexcept \
363  { \
364  return a_lhs.get() a_op a_rhs; \
365  }
366 
367 #define SKSE_MAKE_ARITHMETIC_OP(a_op) \
368  template <class E, class U> \
369  [[nodiscard]] constexpr auto operator a_op(enumeration<E, U> a_enum, U a_shift) noexcept \
370  ->enumeration<E, U> \
371  { \
372  return static_cast<E>(static_cast<U>(a_enum.get()) a_op a_shift); \
373  } \
374  \
375  template <class E, class U> \
376  constexpr auto operator a_op##=(enumeration<E, U>& a_enum, U a_shift) noexcept \
377  ->enumeration<E, U>& \
378  { \
379  return a_enum = a_enum a_op a_shift; \
380  }
381 
382 #define SKSE_MAKE_ENUMERATION_OP(a_op) \
383  template <class E, class U1, class U2> \
384  [[nodiscard]] constexpr auto operator a_op(enumeration<E, U1> a_lhs, enumeration<E, U2> a_rhs) noexcept \
385  ->enumeration<E, std::common_type_t<U1, U2>> \
386  { \
387  return static_cast<E>(static_cast<U1>(a_lhs.get()) a_op static_cast<U2>(a_rhs.get())); \
388  } \
389  \
390  template <class E, class U> \
391  [[nodiscard]] constexpr auto operator a_op(enumeration<E, U> a_lhs, E a_rhs) noexcept \
392  ->enumeration<E, U> \
393  { \
394  return static_cast<E>(static_cast<U>(a_lhs.get()) a_op static_cast<U>(a_rhs)); \
395  } \
396  \
397  template <class E, class U> \
398  [[nodiscard]] constexpr auto operator a_op(E a_lhs, enumeration<E, U> a_rhs) noexcept \
399  ->enumeration<E, U> \
400  { \
401  return static_cast<E>(static_cast<U>(a_lhs) a_op static_cast<U>(a_rhs.get())); \
402  } \
403  \
404  template <class E, class U1, class U2> \
405  constexpr auto operator a_op##=(enumeration<E, U1>& a_lhs, enumeration<E, U2> a_rhs) noexcept \
406  ->enumeration<E, U1>& \
407  { \
408  return a_lhs = a_lhs a_op a_rhs; \
409  } \
410  \
411  template <class E, class U> \
412  constexpr auto operator a_op##=(enumeration<E, U>& a_lhs, E a_rhs) noexcept \
413  ->enumeration<E, U>& \
414  { \
415  return a_lhs = a_lhs a_op a_rhs; \
416  } \
417  \
418  template <class E, class U> \
419  constexpr auto operator a_op##=(E& a_lhs, enumeration<E, U> a_rhs) noexcept \
420  ->E& \
421  { \
422  return a_lhs = *(a_lhs a_op a_rhs); \
423  }
424 
425 #define SKSE_MAKE_INCREMENTER_OP(a_op) \
426  template <class E, class U> \
427  constexpr auto operator a_op##a_op(enumeration<E, U>& a_lhs) noexcept \
428  ->enumeration<E, U>& \
429  { \
430  return a_lhs a_op## = static_cast<E>(1); \
431  } \
432  \
433  template <class E, class U> \
434  [[nodiscard]] constexpr auto operator a_op##a_op(enumeration<E, U>& a_lhs, int) noexcept \
435  ->enumeration<E, U> \
436  { \
437  const auto tmp = a_lhs; \
438  a_op##a_op a_lhs; \
439  return tmp; \
440  }
441 
442 namespace SKSE
443 {
444  namespace stl
445  {
446  template <
447  class E,
448  class U>
449  [[nodiscard]] constexpr auto operator~(enumeration<E, U> a_enum) noexcept
451  {
452  return static_cast<E>(~static_cast<U>(a_enum.get()));
453  }
454 
456  SKSE_MAKE_LOGICAL_OP(<=>, std::strong_ordering);
457 
462 
466 
469 
472 
473  template <class T>
474  class atomic_ref :
475  public std::atomic_ref<T>
476  {
477  private:
478  using super = std::atomic_ref<T>;
479 
480  public:
481  using value_type = typename super::value_type;
482 
483  explicit atomic_ref(volatile T& a_obj) noexcept(std::is_nothrow_constructible_v<super, value_type&>) :
484  super(const_cast<value_type&>(a_obj))
485  {}
486 
487  using super::super;
488  using super::operator=;
489  };
490 
491  template <class T>
492  atomic_ref(volatile T&) -> atomic_ref<T>;
493 
494  template class atomic_ref<std::int8_t>;
495  template class atomic_ref<std::uint8_t>;
496  template class atomic_ref<std::int16_t>;
497  template class atomic_ref<std::uint16_t>;
498  template class atomic_ref<std::int32_t>;
499  template class atomic_ref<std::uint32_t>;
500  template class atomic_ref<std::int64_t>;
501  template class atomic_ref<std::uint64_t>;
502 
511 
512  template <class T>
513  struct ssizeof
514  {
515  [[nodiscard]] constexpr operator std::ptrdiff_t() const noexcept { return value; }
516 
517  [[nodiscard]] constexpr std::ptrdiff_t operator()() const noexcept { return value; }
518 
519  static constexpr auto value = static_cast<std::ptrdiff_t>(sizeof(T));
520  };
521 
522  template <class T>
523  inline constexpr auto ssizeof_v = ssizeof<T>::value;
524 
525  template <class T, class U>
526  [[nodiscard]] auto adjust_pointer(U* a_ptr, std::ptrdiff_t a_adjust) noexcept
527  {
528  auto addr = a_ptr ? reinterpret_cast<std::uintptr_t>(a_ptr) + a_adjust : 0;
529  if constexpr (std::is_const_v<U> && std::is_volatile_v<U>) {
530  return reinterpret_cast<std::add_cv_t<T>*>(addr);
531  } else if constexpr (std::is_const_v<U>) {
532  return reinterpret_cast<std::add_const_t<T>*>(addr);
533  } else if constexpr (std::is_volatile_v<U>) {
534  return reinterpret_cast<std::add_volatile_t<T>*>(addr);
535  } else {
536  return reinterpret_cast<T*>(addr);
537  }
538  }
539 
540  template <class T>
541  void memzero(volatile T* a_ptr, std::size_t a_size = sizeof(T))
542  {
543  const auto begin = reinterpret_cast<volatile char*>(a_ptr);
544  constexpr char val{ 0 };
545  std::fill_n(begin, a_size, val);
546  }
547 
548  template <class... Args>
549  [[nodiscard]] inline auto pun_bits(Args... a_args) //
550  requires(std::same_as<std::remove_cv_t<Args>, bool>&&...)
551  {
552  constexpr auto ARGC = sizeof...(Args);
553 
554  std::bitset<ARGC> bits;
555  std::size_t i = 0;
556  ((bits[i++] = a_args), ...);
557 
558  if constexpr (ARGC <= std::numeric_limits<unsigned long>::digits) {
559  return bits.to_ulong();
560  } else if constexpr (ARGC <= std::numeric_limits<unsigned long long>::digits) {
561  return bits.to_ullong();
562  } else {
563  static_assert(false && sizeof...(Args));
564  }
565  }
566 
567  [[nodiscard]] inline auto utf8_to_utf16(std::string_view a_in) noexcept
568  -> std::optional<std::wstring>
569  {
570  const auto cvt = [&](wchar_t* a_dst, std::size_t a_length) {
573  0,
574  a_in.data(),
575  static_cast<int>(a_in.length()),
576  a_dst,
577  static_cast<int>(a_length));
578  };
579 
580  const auto len = cvt(nullptr, 0);
581  if (len == 0) {
582  return std::nullopt;
583  }
584 
585  std::wstring out(len, '\0');
586  if (cvt(out.data(), out.length()) == 0) {
587  return std::nullopt;
588  }
589 
590  return out;
591  }
592 
593  [[nodiscard]] inline auto utf16_to_utf8(std::wstring_view a_in) noexcept
594  -> std::optional<std::string>
595  {
596  const auto cvt = [&](char* a_dst, std::size_t a_length) {
599  0,
600  a_in.data(),
601  static_cast<int>(a_in.length()),
602  a_dst,
603  static_cast<int>(a_length),
604  nullptr,
605  nullptr);
606  };
607 
608  const auto len = cvt(nullptr, 0);
609  if (len == 0) {
610  return std::nullopt;
611  }
612 
613  std::string out(len, '\0');
614  if (cvt(out.data(), out.length()) == 0) {
615  return std::nullopt;
616  }
617 
618  return out;
619  }
620 
621  [[noreturn]] inline void report_and_fail(std::string_view a_msg, std::source_location a_loc = std::source_location::current())
622  {
623  const auto body = [&]() {
624  const std::filesystem::path p = a_loc.file_name();
625  auto filename = p.lexically_normal().generic_string();
626 
627  const std::regex r{ R"((?:^|[\\\/])(?:include|src)[\\\/](.*)$)" };
628  std::smatch matches;
629  if (std::regex_search(filename, matches, r)) {
630  filename = matches[1].str();
631  }
632 
633  return utf8_to_utf16(
634  fmt::format(
635  "{}({}): {}"sv,
636  filename,
637  a_loc.line(),
638  a_msg))
639  .value_or(L"<character encoding error>"s);
640  }();
641 
642  const auto caption = []() {
643  const auto maxPath = WinAPI::GetMaxPath();
644  std::vector<wchar_t> buf;
645  buf.reserve(maxPath);
646  buf.resize(maxPath / 2);
647  std::uint32_t result = 0;
648  do {
649  buf.resize(buf.size() * 2);
650  result = WinAPI::GetModuleFileName(
652  buf.data(),
653  static_cast<std::uint32_t>(buf.size()));
654  } while (result && result == buf.size() && buf.size() <= std::numeric_limits<std::uint32_t>::max());
655 
656  if (result && result != buf.size()) {
657  std::filesystem::path p(buf.begin(), buf.begin() + result);
658  return p.filename().native();
659  } else {
660  return L""s;
661  }
662  }();
663 
664  spdlog::log(
665  spdlog::source_loc{
666  a_loc.file_name(),
667  static_cast<int>(a_loc.line()),
668  a_loc.function_name() },
669  spdlog::level::critical,
670  a_msg);
671  WinAPI::MessageBox(nullptr, body.c_str(), (caption.empty() ? nullptr : caption.c_str()), 0);
673  }
674 
675  template <class Enum>
676  [[nodiscard]] constexpr auto to_underlying(Enum a_val) noexcept //
677  requires(std::is_enum_v<Enum>)
678  {
679  return static_cast<std::underlying_type_t<Enum>>(a_val);
680  }
681 
682  template <class To, class From>
683  [[nodiscard]] To unrestricted_cast(From a_from) noexcept
684  {
685  if constexpr (std::is_same_v<
686  std::remove_cv_t<From>,
687  std::remove_cv_t<To>>) {
688  return To{ a_from };
689 
690  // From != To
691  } else if constexpr (std::is_reference_v<From>) {
692  return stl::unrestricted_cast<To>(std::addressof(a_from));
693 
694  // From: NOT reference
695  } else if constexpr (std::is_reference_v<To>) {
696  return *stl::unrestricted_cast<
697  std::add_pointer_t<
698  std::remove_reference_t<To>>>(a_from);
699 
700  // To: NOT reference
701  } else if constexpr (std::is_pointer_v<From> &&
702  std::is_pointer_v<To>) {
703  return static_cast<To>(
704  const_cast<void*>(
705  static_cast<const volatile void*>(a_from)));
706  } else if constexpr ((std::is_pointer_v<From> && std::is_integral_v<To>) ||
707  (std::is_integral_v<From> && std::is_pointer_v<To>)) {
708  return reinterpret_cast<To>(a_from);
709  } else {
710  union
711  {
712  std::remove_cv_t<std::remove_reference_t<From>> from;
713  std::remove_cv_t<std::remove_reference_t<To>> to;
714  };
715 
716  from = std::forward<From>(a_from);
717  return to;
718  }
719  }
720  }
721 }
722 
723 #undef SKSE_MAKE_INCREMENTER_OP
724 #undef SKSE_MAKE_ENUMERATION_OP
725 #undef SKSE_MAKE_ARITHMETIC_OP
726 #undef SKSE_MAKE_LOGICAL_OP
727 
728 namespace RE
729 {
730  using namespace std::literals;
731  namespace stl = SKSE::stl;
732  namespace WinAPI = SKSE::WinAPI;
733 }
734 
735 namespace REL
736 {
737  using namespace std::literals;
738  namespace stl = SKSE::stl;
739  namespace WinAPI = SKSE::WinAPI;
740 }
741 
742 #include "REL/Relocation.h"
743 
744 #ifndef SKYRIMVR
745 # include "RE/Offsets.h"
746 # include "RE/Offsets_NiRTTI.h"
747 # include "RE/Offsets_RTTI.h"
748 #else
749 # include "RE/Offsets_NiRTTI_VR.h"
750 # include "RE/Offsets_RTTI_VR.h"
751 # include "RE/Offsets_VR.h"
752 # include "vr/OpenVR.h"
753 #endif
754 
755 #include "RE/B/BSCoreTypes.h"
756 #include "RE/S/SFTypes.h"
Definition: PCH.h:476
typename super::value_type value_type
Definition: PCH.h:481
atomic_ref(volatile T &a_obj) noexcept(std::is_nothrow_constructible_v< super, value_type & >)
Definition: PCH.h:483
Definition: PCH.h:257
Underlying underlying_type
Definition: PCH.h:260
constexpr enum_type operator*() const noexcept
Definition: PCH.h:301
constexpr bool none(Args... a_args) const noexcept requires(std
Definition: PCH.h:336
constexpr enumeration(Args... a_values) noexcept requires(std
Definition: PCH.h:277
Enum enum_type
Definition: PCH.h:259
constexpr enumeration & operator=(enum_type a_value) noexcept
Definition: PCH.h:293
constexpr bool all(Args... a_args) const noexcept requires(std
Definition: PCH.h:329
~enumeration() noexcept=default
constexpr enumeration & reset(Args... a_args) noexcept requires(std
Definition: PCH.h:314
constexpr enumeration & set(Args... a_args) noexcept requires(std
Definition: PCH.h:306
constexpr underlying_type underlying() const noexcept
Definition: PCH.h:303
constexpr enumeration() noexcept=default
constexpr bool any(Args... a_args) const noexcept requires(std
Definition: PCH.h:322
constexpr enum_type get() const noexcept
Definition: PCH.h:302
Definition: Relocation.h:60
Definition: AbsorbEffect.h:6
Definition: WinAPI.h:4
std::size_t GetMaxPath() noexcept
void * GetCurrentModule() noexcept
std::uint32_t GetModuleFileName(void *a_module, char *a_filename, std::uint32_t a_size) noexcept
int MultiByteToWideChar(unsigned int a_codePage, std::uint32_t a_flags, const char *a_multiByteStr, int a_multiByte, wchar_t *a_wideCharStr, int a_wideChar)
std::int32_t MessageBox(void *a_wnd, const char *a_text, const char *a_caption, unsigned int a_type) noexcept
constexpr auto CP_UTF8
Definition: WinAPI.h:5
int WideCharToMultiByte(unsigned int a_codePage, std::uint32_t a_flags, const wchar_t *a_wideCharStr, int a_wideChar, char *a_multiByteStr, int a_multiByte, const char *a_defaultChar, int *a_usedDefaultChar)
void * GetCurrentProcess() noexcept
void TerminateProcess(void *a_process, unsigned int a_exitCode) noexcept
string(const CharT(&)[N]) -> string< CharT, N - 1 >
Definition: PCH.h:73
atomic_ref(volatile T &) -> atomic_ref< T >
T not_null
Definition: PCH.h:99
SKSE_MAKE_ENUMERATION_OP(<<)
constexpr auto to_underlying(Enum a_val) noexcept requires(std
Definition: PCH.h:676
To unrestricted_cast(From a_from) noexcept
Definition: PCH.h:683
std::basic_string_view< CharT > basic_zstring
Definition: PCH.h:75
void memzero(volatile T *a_ptr, std::size_t a_size=sizeof(T))
Definition: PCH.h:541
void report_and_fail(std::string_view a_msg, std::source_location a_loc=std::source_location::current())
Definition: PCH.h:621
scope_exit(EF) -> scope_exit< EF >
T owner
Definition: PCH.h:85
T observer
Definition: PCH.h:92
auto utf16_to_utf8(std::wstring_view a_in) noexcept -> std::optional< std::string >
Definition: PCH.h:593
SKSE_MAKE_INCREMENTER_OP(+)
auto adjust_pointer(U *a_ptr, std::ptrdiff_t a_adjust) noexcept
Definition: PCH.h:526
auto utf8_to_utf16(std::string_view a_in) noexcept -> std::optional< std::wstring >
Definition: PCH.h:567
requires(std::invocable< std::remove_reference_t< EF >>) class scope_exit
Definition: PCH.h:190
SKSE_MAKE_LOGICAL_OP(==, bool)
basic_zstring< wchar_t > zwstring
Definition: PCH.h:78
constexpr auto operator~(enumeration< E, U > a_enum) noexcept -> enumeration< E, U >
Definition: PCH.h:449
auto pun_bits(Args... a_args) requires(std
Definition: PCH.h:549
SKSE_MAKE_ARITHMETIC_OP(<<)
basic_zstring< char > zstring
Definition: PCH.h:77
enumeration(Args...) -> enumeration< std::common_type_t< Args... >, std::underlying_type_t< std::common_type_t< Args... >>>
constexpr auto ssizeof_v
Definition: PCH.h:523
Definition: API.h:14
Definition: PCH.h:105
consteval bool empty() const noexcept
Definition: PCH.h:130
const char_type & const_reference
Definition: PCH.h:110
consteval auto substr() const noexcept
Definition: PCH.h:136
consteval const_reference operator[](size_type a_pos) const noexcept
Definition: PCH.h:122
const char_type * const_pointer
Definition: PCH.h:108
consteval const_pointer data() const noexcept
Definition: PCH.h:129
std::size_t size_type
Definition: PCH.h:111
consteval const_reference back() const noexcept
Definition: PCH.h:128
consteval string(const_pointer a_string) noexcept
Definition: PCH.h:115
char_type & reference
Definition: PCH.h:109
char_type * pointer
Definition: PCH.h:107
consteval size_type length() const noexcept
Definition: PCH.h:132
consteval size_type size() const noexcept
Definition: PCH.h:133
consteval const_reference front() const noexcept
Definition: PCH.h:131
CharT char_type
Definition: PCH.h:106
Definition: PCH.h:149
consteval zstring(const char_type(&a_string)[N]) noexcept
Definition: PCH.h:159
std::size_t size_type
Definition: PCH.h:155
consteval const_pointer data() const noexcept
Definition: PCH.h:173
consteval const_reference back() const noexcept
Definition: PCH.h:172
const char_type * const_pointer
Definition: PCH.h:152
consteval const_reference front() const noexcept
Definition: PCH.h:175
consteval size_type length() const noexcept
Definition: PCH.h:176
const char_type & const_reference
Definition: PCH.h:154
consteval size_type size() const noexcept
Definition: PCH.h:177
CharT char_type
Definition: PCH.h:150
char_type * pointer
Definition: PCH.h:151
char_type & reference
Definition: PCH.h:153
consteval const_reference operator[](size_type a_pos) const noexcept
Definition: PCH.h:166
consteval bool empty() const noexcept
Definition: PCH.h:174
consteval auto substr() const noexcept
Definition: PCH.h:180
Definition: PCH.h:514
constexpr std::ptrdiff_t operator()() const noexcept
Definition: PCH.h:517