LeviLamina
Loading...
Searching...
No Matches
DynamicValue.h
1#pragma once
2
3#include <concepts>
4#include <initializer_list>
5
6#include "mc/_HeaderOutputPredefine.h"
7
8// auto generated inclusion list
9#include "mc/deps/cereal/schema/dynamic/NullType.h"
10#include "mc/external/cereal/StringViewHash.h"
11
12namespace cereal {
13
14class DynamicValue {
15public:
16 // DynamicValue inner types define
17 enum class Type : int {
18 Null = 0,
19 Boolean = 1,
20 Integer = 2,
21 Number = 3,
22 String = 4,
23 Array = 5,
24 Object = 6,
25 };
26
27 using Array = ::std::vector<::cereal::DynamicValue>;
28
29 using Bool = bool;
30
31 using Integer = int64;
32
33 using Null = ::cereal::NullType;
34
35 using Number = double;
36
37 using String = ::std::string;
38
39 using Object = ::std::
40 unordered_map<String, ::cereal::DynamicValue, ::cereal::util::internal::StringViewHash, ::std::equal_to<void>>;
41
42 using Member = ::std::pair<::std::string, ::cereal::DynamicValue>;
43
44 using Variant = ::std::variant<::cereal::NullType, bool, int64, double, ::std::string, Array, Object>;
45
46public:
47 // member variables
48 // NOLINTBEGIN
49 Variant mValue;
50 // NOLINTEND
51
52public:
53 DynamicValue() = default;
54
55 DynamicValue(::std::nullptr_t) noexcept : mValue(Null{}) {}
56 DynamicValue(Null) noexcept : mValue(Null{}) {}
57 DynamicValue(Bool value) noexcept : mValue(value) {}
58
59 template <::std::integral T>
60 requires(!::std::same_as<::std::remove_cvref_t<T>, Bool>)
61 DynamicValue(T value) noexcept : mValue(static_cast<Integer>(value)) {}
62
63 template <::std::floating_point T>
64 DynamicValue(T value) noexcept : mValue(static_cast<Number>(value)) {}
65
66 DynamicValue(char const* value) : mValue(String{value == nullptr ? "" : value}) {}
67 DynamicValue(::std::string_view value) : mValue(String{value}) {}
68 DynamicValue(String value) : mValue(::std::move(value)) {}
69 DynamicValue(Array value) : mValue(::std::move(value)) {}
70 DynamicValue(Object value) : mValue(::std::move(value)) {}
71
72 DynamicValue(DynamicValue const&) = default;
73 DynamicValue(DynamicValue&&) = default;
74 DynamicValue& operator=(DynamicValue const&) = default;
75 DynamicValue& operator=(DynamicValue&&) = default;
76
77 template <class T>
78 requires(!::std::same_as<::std::remove_cvref_t<T>, DynamicValue> && ::std::constructible_from<DynamicValue, T>)
79 DynamicValue& operator=(T&& value) {
80 return *this = DynamicValue(::std::forward<T>(value));
81 }
82
83 [[nodiscard]] static DynamicValue array() { return Array{}; }
84
85 [[nodiscard]] static DynamicValue array(::std::initializer_list<DynamicValue> values) { return Array{values}; }
86
87 [[nodiscard]] static DynamicValue object() { return Object{}; }
88
89 [[nodiscard]] static DynamicValue object(::std::initializer_list<Member> members) {
90 Object result;
91 result.reserve(members.size());
92 for (auto const& [name, value] : members) {
93 result.insert_or_assign(name, value);
94 }
95 return result;
96 }
97
98 [[nodiscard]] Variant const& value() const& noexcept { return mValue; }
99 [[nodiscard]] Variant& value() & noexcept { return mValue; }
100 [[nodiscard]] Variant&& value() && noexcept { return ::std::move(mValue); }
101
102 template <class T>
103 [[nodiscard]] bool is() const noexcept {
104 return ::std::holds_alternative<T>(value());
105 }
106
107 template <class T>
108 [[nodiscard]] T const& get() const& {
109 return ::std::get<T>(value());
110 }
111
112 template <class T>
113 [[nodiscard]] T& get() & {
114 return ::std::get<T>(value());
115 }
116
117 template <class T>
118 [[nodiscard]] T&& get() && {
119 return ::std::get<T>(::std::move(*this).value());
120 }
121
122 template <class T>
123 [[nodiscard]] T const* getIf() const noexcept {
124 return ::std::get_if<T>(&value());
125 }
126
127 template <class T>
128 [[nodiscard]] T* getIf() noexcept {
129 return ::std::get_if<T>(&value());
130 }
131
132 [[nodiscard]] bool isNull() const noexcept { return is<Null>(); }
133 [[nodiscard]] bool isBool() const noexcept { return is<Bool>(); }
134 [[nodiscard]] bool isInteger() const noexcept { return is<Integer>(); }
135 [[nodiscard]] bool isNumber() const noexcept { return is<Number>(); }
136 [[nodiscard]] bool isString() const noexcept { return is<String>(); }
137 [[nodiscard]] bool isArray() const noexcept { return is<Array>(); }
138 [[nodiscard]] bool isObject() const noexcept { return is<Object>(); }
139 [[nodiscard]] bool isNumeric() const noexcept { return isInteger() || isNumber(); }
140 [[nodiscard]] bool isPrimitive() const noexcept { return !isArray() && !isObject(); }
141
142 [[nodiscard]] Type type() const noexcept { return static_cast<Type>(value().index()); }
143
144 [[nodiscard]] Null const& asNull() const { return get<Null>(); }
145 [[nodiscard]] Null& asNull() { return get<Null>(); }
146 [[nodiscard]] Bool const& asBool() const { return get<Bool>(); }
147 [[nodiscard]] Bool& asBool() { return get<Bool>(); }
148 [[nodiscard]] Integer const& asInteger() const { return get<Integer>(); }
149 [[nodiscard]] Integer& asInteger() { return get<Integer>(); }
150 [[nodiscard]] Number const& asNumber() const { return get<Number>(); }
151 [[nodiscard]] Number& asNumber() { return get<Number>(); }
152 [[nodiscard]] String const& asString() const { return get<String>(); }
153 [[nodiscard]] String& asString() { return get<String>(); }
154 [[nodiscard]] Array const& asArray() const { return get<Array>(); }
155 [[nodiscard]] Array& asArray() { return get<Array>(); }
156 [[nodiscard]] Object const& asObject() const { return get<Object>(); }
157 [[nodiscard]] Object& asObject() { return get<Object>(); }
158
159 [[nodiscard]] bool contains(::std::string_view member) const {
160 if (!isObject()) {
161 return false;
162 }
163 return get<Object>().contains(member);
164 }
165
166 [[nodiscard]] ::std::size_t size() const noexcept {
167 if (auto const* values = ::std::get_if<Array>(&value())) {
168 return values->size();
169 }
170 if (auto const* members = ::std::get_if<Object>(&value())) {
171 return members->size();
172 }
173 return isNull() ? 0 : 1;
174 }
175
176 [[nodiscard]] bool empty() const noexcept { return size() == 0; }
177
178 [[nodiscard]] bool hasMember(::std::string_view member) const { return contains(member); }
179
180 DynamicValue& operator[](::std::string_view member) {
181 if (isNull()) {
182 mValue = Object{};
183 }
184 auto& values = get<Object>();
185 if (auto iter = values.find(member); iter != values.end()) {
186 return iter->second;
187 }
188 return values.try_emplace(String{member}).first->second;
189 }
190
191 DynamicValue const& operator[](::std::string_view member) const {
192 auto const& values = get<Object>();
193 auto iter = values.find(member);
194 if (iter == values.end()) {
195 throw ::std::out_of_range("DynamicValue object key not found");
196 }
197 return iter->second;
198 }
199
200 DynamicValue& operator[](::std::size_t index) { return get<Array>().at(index); }
201
202 DynamicValue const& operator[](::std::size_t index) const { return get<Array>().at(index); }
203
204 DynamicValue& at(::std::string_view member) { return const_cast<DynamicValue&>(::std::as_const(*this).at(member)); }
205
206 DynamicValue const& at(::std::string_view member) const { return operator[](member); }
207
208 DynamicValue& at(::std::size_t index) { return get<Array>().at(index); }
209
210 DynamicValue const& at(::std::size_t index) const { return get<Array>().at(index); }
211
212 template <class T>
213 requires ::std::constructible_from<DynamicValue, T>
214 DynamicValue& set(::std::string_view member, T&& field) {
215 (*this)[member] = DynamicValue(::std::forward<T>(field));
216 return *this;
217 }
218
219 DynamicValue& pushBack(DynamicValue element) {
220 if (isNull()) {
221 mValue = Array{};
222 }
223 get<Array>().emplace_back(::std::move(element));
224 return *this;
225 }
226
227 DynamicValue& push_back(DynamicValue element) { return pushBack(::std::move(element)); }
228
229 template <class T>
230 requires ::std::constructible_from<DynamicValue, T>
231 DynamicValue& emplaceBack(T&& element) {
232 return pushBack(DynamicValue(::std::forward<T>(element)));
233 }
234
235 template <class T>
236 requires ::std::constructible_from<DynamicValue, T>
237 DynamicValue& emplace_back(T&& element) {
238 return emplaceBack(::std::forward<T>(element));
239 }
240
241 bool erase(::std::string_view member) {
242 if (!isObject()) {
243 return false;
244 }
245 auto& values = get<Object>();
246 auto iter = values.find(member);
247 if (iter == values.end()) {
248 return false;
249 }
250 values.erase(iter);
251 return true;
252 }
253
254 void erase(::std::size_t index) {
255 auto& values = get<Array>();
256 if (index >= values.size()) {
257 throw ::std::out_of_range("DynamicValue array index out of range");
258 }
259 values.erase(values.begin() + static_cast<::std::ptrdiff_t>(index));
260 }
261
262 void clear() {
263 if (auto* values = getIf<Array>()) {
264 values->clear();
265 } else if (auto* members = getIf<Object>()) {
266 members->clear();
267 } else if (auto* text = getIf<String>()) {
268 text->clear();
269 } else {
270 *this = nullptr;
271 }
272 }
273
274 void reserve(::std::size_t capacity) {
275 if (auto* values = getIf<Array>()) {
276 values->reserve(capacity);
277 } else {
278 get<Object>().reserve(capacity);
279 }
280 }
281
282 MCAPI uint64 hash() const;
283 // NOLINTEND
284};
285
286[[nodiscard]] inline bool operator==(DynamicValue const& lhs, DynamicValue const& rhs) {
287 return lhs.value() == rhs.value();
288}
289
290} // namespace cereal
291
292namespace std {
293
294template <>
295struct hash<::cereal::DynamicValue> {
296 [[nodiscard]] ::std::size_t operator()(::cereal::DynamicValue const& value) const {
297 return static_cast<::std::size_t>(value.hash());
298 }
299};
300
301} // namespace std
Definition DynamicValue.h:14
STL namespace.
Definition NullType.h:7