LeviLamina
Loading...
Searching...
No Matches
Signature.h
1#pragma once
2
3#include <array>
4#include <memory>
5#include <optional>
6#include <span>
7#include <string>
8#include <string_view>
9#include <vector>
10
11#include "ll/api/base/FixedString.h"
12#include "ll/api/base/Macro.h"
13#include "ll/api/base/StdInt.h"
14#include "ll/api/utils/HashUtils.h"
15#include "ll/api/utils/StringUtils.h"
16
17namespace ll::memory {
18
19class Signature;
20template <size_t N>
21class FixedSignature;
22
24 std::optional<std::byte> element;
25
26public:
27 [[nodiscard]] constexpr SignatureElement() = default;
28
29 [[nodiscard]] constexpr SignatureElement(std::nullptr_t) {}
30
31 [[nodiscard]] constexpr SignatureElement(std::byte byte) : element(byte) {}
32
33 [[nodiscard]] constexpr SignatureElement(uchar byte) : element(static_cast<std::byte>(byte)) {}
34
35 [[nodiscard]] constexpr std::byte operator*() const { return *element; }
36
37 [[nodiscard]] constexpr bool isWildcard() const { return !element.has_value(); }
38
39 [[nodiscard]] constexpr bool operator==(SignatureElement const& other) const { return element == other.element; }
40
41 [[nodiscard]] constexpr bool operator==(std::byte other) const { return isWildcard() || *element == other; }
42
43 [[nodiscard]] constexpr bool operator==(uchar other) const { return operator==(static_cast<std::byte>(other)); }
44
45 [[nodiscard]] size_t hash() const { return std::hash<std::optional<std::byte>>{}(element); }
46};
47
49 std::span<SignatureElement const> elements;
50
51 void* uncachedResolve(std::span<std::byte> range) const;
52
53public:
54 [[nodiscard]] constexpr SignatureView() = default;
55
56 [[nodiscard]] constexpr SignatureView(SignatureView&&) noexcept = default;
57 LL_MAY_CONSTEXPR SignatureView& operator=(SignatureView&&) noexcept = default;
58 [[nodiscard]] constexpr SignatureView(SignatureView const&) noexcept = default;
59 LL_MAY_CONSTEXPR SignatureView& operator=(SignatureView const&) noexcept = default;
60
61 [[nodiscard]] constexpr SignatureView(std::span<SignatureElement const> span) : elements(span) {}
62
63 [[nodiscard]] constexpr SignatureView(Signature const& signature);
64 template <size_t N>
65 [[nodiscard]] constexpr SignatureView(FixedSignature<N> const& signature);
66
67 [[nodiscard]] constexpr auto begin() const { return elements.begin(); }
68 [[nodiscard]] constexpr auto end() const { return elements.end(); }
69 [[nodiscard]] constexpr decltype(auto) front() const { return elements.front(); }
70 [[nodiscard]] constexpr decltype(auto) back() const { return elements.back(); }
71 [[nodiscard]] constexpr decltype(auto) operator[](size_t idx) const { return elements[idx]; }
72
73 [[nodiscard]] constexpr size_t size() const { return elements.size(); }
74
75 LLNDAPI void* resolve(bool disableErrorOutput = false) const;
76 LLNDAPI void* resolve(std::span<std::byte> range, bool disableErrorOutput = false) const;
77
78 LLNDAPI std::string toString(bool alignWildcard = true, bool upperCase = true) const;
79
80 [[nodiscard]] constexpr bool operator==(SignatureView const& other) const {
81 return std::equal(begin(), end(), other.begin(), other.end());
82 }
83};
84
85class Signature {
86 std::vector<SignatureElement> elements;
87
88 [[nodiscard]] constexpr Signature(std::vector<SignatureElement> vec) : elements(std::move(vec)) {}
89
90public:
91 [[nodiscard]] explicit constexpr Signature(SignatureView view) : elements(view.begin(), view.end()) {}
92
93 [[nodiscard]] static constexpr Signature parse(std::string_view str) {
94 std::vector<SignatureElement> elements;
95 string_utils::splitByPattern(
96 [&](std::string_view sv) {
97 if (sv.starts_with('?')) {
98 elements.emplace_back();
99 } else {
100 elements.emplace_back(string_utils::digitFromChar(sv[0]) << 4 | string_utils::digitFromChar(sv[1]));
101 }
102 return true;
103 },
104 str,
105 " "
106 );
107 return {std::move(elements)};
108 }
109
110 [[nodiscard]] constexpr auto begin() const { return elements.begin(); }
111 [[nodiscard]] constexpr auto end() const { return elements.end(); }
112 [[nodiscard]] constexpr decltype(auto) front() const { return elements.front(); }
113 [[nodiscard]] constexpr decltype(auto) back() const { return elements.back(); }
114 [[nodiscard]] constexpr decltype(auto) operator[](size_t idx) const { return elements[idx]; }
115
116 [[nodiscard]] constexpr size_t size() const { return elements.size(); }
117
118 [[nodiscard]] constexpr SignatureView view() const { return {std::span{elements}}; }
119
120 [[nodiscard]] constexpr bool operator==(Signature const& other) const { return elements == other.elements; }
121};
122
123[[nodiscard]] constexpr SignatureView::SignatureView(Signature const& signature) : SignatureView(signature.view()) {}
124
125template <size_t N>
127 std::array<SignatureElement, N> elements;
128
129public:
130 [[nodiscard]] constexpr FixedSignature(SignatureView signature) {
131 for (size_t i = 0; i < N; ++i) {
132 elements[i] = signature[i];
133 }
134 }
135
136 [[nodiscard]] auto begin() const { return elements.begin(); }
137 [[nodiscard]] auto end() const { return elements.end(); }
138 [[nodiscard]] constexpr decltype(auto) front() const { return elements.front(); }
139 [[nodiscard]] constexpr decltype(auto) back() const { return elements.back(); }
140 [[nodiscard]] constexpr decltype(auto) operator[](size_t idx) const { return elements[idx]; }
141
142 [[nodiscard]] consteval size_t size() const { return N; }
143
144 [[nodiscard]] constexpr SignatureView view() const { return {std::span{elements}}; }
145};
146
147template <size_t N>
148[[nodiscard]] constexpr SignatureView::SignatureView(FixedSignature<N> const& signature)
149: SignatureView(signature.view()) {}
150
151template <FixedString signature>
152constexpr inline auto signatureCache = []() {
153 constexpr size_t N = []() {
154 size_t i = 0;
155 string_utils::splitByPattern(
156 [&](std::string_view) {
157 i++;
158 return true;
159 },
160 signature,
161 " "
162 );
163 return i;
164 }();
165 FixedSignature<N> res{Signature::parse(signature)};
166 return res;
167}();
168} // namespace ll::memory
169
170namespace ll::inline literals::inline memory_literals {
171template <FixedString signature>
172consteval memory::SignatureView operator""_sig() noexcept {
173 return memory::signatureCache<signature>.view();
174}
175template <FixedString signature>
176constexpr void* operator""_sigp() noexcept {
177 return memory::signatureCache<signature>.view().resolve();
178}
179} // namespace ll::inline literals::inline memory_literals
180
181namespace std {
182template <>
183struct hash<ll::memory::SignatureElement> {
184 size_t operator()(ll::memory::SignatureElement const& e) const noexcept { return e.hash(); }
185};
186template <>
187struct hash<ll::memory::Signature> {
188 size_t operator()(ll::memory::Signature const& s) const noexcept {
189 return ll::hash_utils::HashCombiner{s.size()}.addRange(s);
190 }
191};
192template <>
193struct hash<ll::memory::SignatureView> {
194 size_t operator()(ll::memory::SignatureView const& s) const noexcept {
195 return ll::hash_utils::HashCombiner{s.size()}.addRange(s);
196 }
197};
198} // namespace std
Definition Signature.h:126
Definition Signature.h:23
Definition Signature.h:48
Definition Signature.h:85
STL namespace.