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