13 return (
'0' <= a_ch && a_ch <=
'9') ||
14 (
'A' <= a_ch && a_ch <=
'F') ||
15 (
'a' <= a_ch && a_ch <=
'f');
18 [[nodiscard]] constexpr
bool space(
char a_ch) noexcept
23 [[nodiscard]] constexpr
bool wildcard(
char a_ch) noexcept
35 constexpr
auto lut = []() noexcept {
38 const auto iterate = [&](std::uint8_t a_iFirst,
unsigned char a_cFirst,
unsigned char a_cLast) noexcept {
39 for (; a_cFirst <= a_cLast; ++a_cFirst, ++a_iFirst) {
40 a[a_cFirst] = a_iFirst;
45 iterate(0xA,
'A',
'F');
46 iterate(0xa,
'a',
'f');
51 return static_cast<std::byte
>(
52 lut[
static_cast<unsigned char>(a_hi)] * 0x10u +
53 lut[
static_cast<unsigned char>(a_lo)]);
57 template <
char HI,
char LO>
61 [[nodiscard]]
static constexpr
bool match(std::byte a_byte) noexcept
64 return a_byte == expected;
83 [[nodiscard]]
static constexpr
bool match(std::byte) noexcept
97 template <
char C1,
char C2>
101 template <
char C1,
char C2>
106 template <class... Rules>
110 static_assert(
sizeof...(Rules) >= 1,
"must provide at least 1 rule for the pattern matcher");
112 [[nodiscard]] constexpr
bool match(std::span<
const std::byte,
sizeof...(Rules)> a_bytes)
const noexcept
115 return (Rules::match(a_bytes[i++]) && ...);
118 [[nodiscard]]
bool match(std::uintptr_t a_address)
const noexcept
120 return this->match(*
reinterpret_cast<const std::byte(*)[sizeof...(Rules)]
>(a_address));
123 void match_or_fail(std::uintptr_t a_address, std::source_location a_loc = std::source_location::current()) const noexcept
125 if (!this->match(a_address)) {
129 "A pattern has failed to match.\n"
130 "This means the plugin is incompatible with the current version of the game ({}.{}.{}). "
131 "Head to the mod page of this plugin to see if an update is available."sv,
145 if constexpr (S.length() == 0) {
147 }
else if constexpr (S.length() == 1) {
148 constexpr
char c = S[0];
150 consteval_error(
"the given pattern has an unpaired rule (rules are required to be written in pairs of 2)");
152 consteval_error(
"the given pattern has trailing characters at the end (which is not allowed)");
156 if constexpr (std::same_as<rule_t, void>) {
159 if constexpr (S.length() <= 3) {
164 consteval_error(
"a space character is required to split byte patterns");
170 template <
class... Bytes>
172 -> std::array<std::byte,
sizeof...(Bytes)>
174 static_assert((std::integral<Bytes> && ...),
"all bytes must be an integral type");
175 return {
static_cast<std::byte
>(a_bytes)... };
179 template <stl::nttp::
string S>
182 return detail::do_make_pattern<S>();
185 static_assert(make_pattern<"40 10 F2 ??">().match(
187 static_assert(make_pattern<"B8 D0 ?? ?? D4 6E">().match(
static Module & get()
Definition: Module.h:54
Version version() const noexcept
Definition: Module.h:62
Definition: Pattern.h:108
constexpr bool match(std::span< const std::byte, sizeof...(Rules)> a_bytes) const noexcept
Definition: Pattern.h:112
void match_or_fail(std::uintptr_t a_address, std::source_location a_loc=std::source_location::current()) const noexcept
Definition: Pattern.h:123
bool match(std::uintptr_t a_address) const noexcept
Definition: Pattern.h:118
static constexpr bool match(std::byte a_byte) noexcept
Definition: Pattern.h:61
static constexpr bool match(std::byte) noexcept
Definition: Pattern.h:83
constexpr bool space(char a_ch) noexcept
Definition: Pattern.h:18
constexpr bool hexadecimal(char a_ch) noexcept
Definition: Pattern.h:11
constexpr bool wildcard(char a_ch) noexcept
Definition: Pattern.h:23
consteval std::byte hexacharacters_to_hexadecimal(char a_hi, char a_lo) noexcept
Definition: Pattern.h:33
consteval auto make_byte_array(Bytes... a_bytes) noexcept -> std::array< std::byte, sizeof...(Bytes)>
Definition: Pattern.h:171
void consteval_error(const char *a_error)
constexpr auto do_make_pattern() noexcept
Definition: Pattern.h:143
constexpr auto make_pattern() noexcept
Definition: Pattern.h:180
NiColor max(const NiColor &a_lhs, const NiColor &a_rhs)
Definition: ColorUtil.h:71
string(const CharT(&)[N]) -> string< CharT, N - 1 >
void report_and_fail(std::string_view a_msg, std::source_location a_loc=std::source_location::current())
Definition: PCH.h:396
requires(std::invocable< std::remove_reference_t< EF >>) class scope_exit
Definition: PCH.h:153