LeviLamina
Loading...
Searching...
No Matches
CompoundTagVariant.h
1#pragma once
2
3#include "mc/_HeaderOutputPredefine.h"
4#include "mc/nbt/ByteArrayTag.h"
5#include "mc/nbt/ByteTag.h"
6#include "mc/nbt/CompoundTag.h"
7#include "mc/nbt/DoubleTag.h"
8#include "mc/nbt/EndTag.h"
9#include "mc/nbt/FloatTag.h"
10#include "mc/nbt/Int64Tag.h"
11#include "mc/nbt/IntArrayTag.h"
12#include "mc/nbt/IntTag.h"
13#include "mc/nbt/ListTag.h"
14#include "mc/nbt/ShortTag.h"
15#include "mc/nbt/StringTag.h"
16
17#include "ll/api/Expected.h"
18#include "ll/api/base/Concepts.h"
19#include "ll/api/base/Meta.h"
20
21// auto generated inclusion list
22#include "mc/nbt/ByteArrayTag.h"
23#include "mc/nbt/ByteTag.h"
24#include "mc/nbt/CompoundTag.h"
25#include "mc/nbt/DoubleTag.h"
26#include "mc/nbt/EndTag.h"
27#include "mc/nbt/FloatTag.h"
28#include "mc/nbt/Int64Tag.h"
29#include "mc/nbt/IntArrayTag.h"
30#include "mc/nbt/IntTag.h"
31#include "mc/nbt/ListTag.h"
32#include "mc/nbt/ShortTag.h"
33#include "mc/nbt/StringTag.h"
34
35// auto generated forward declare list
36// clang-format off
37class Tag;
38// clang-format on
39
41public:
42 // CompoundTagVariant inner types define
56
57 using Variant = Types::to<::std::variant>;
58
59 template <bool Const>
60 class Iterator {
61 public:
62 using iterator_category = std::bidirectional_iterator_tag;
63 using difference_type = ptrdiff_t;
64 using value_type = Tag;
65 using reference = std::conditional_t<Const, value_type const, value_type>&;
66 using pointer = std::add_pointer_t<reference>;
67
68 std::conditional_t<
69 Const,
70 std::variant<CompoundTagVariant const*, CompoundTag::const_iterator, ListTag::const_iterator>,
71 std::variant<CompoundTagVariant*, CompoundTag::iterator, ListTag::iterator>>
72 iter;
73
74 static Iterator makeBegin(auto& var) noexcept {
75 Iterator res;
76 switch (var.index()) {
77 case Tag::List:
78 res.iter.template emplace<2>(var.get<ListTag>().begin());
79 break;
80 case Tag::Compound:
81 res.iter.template emplace<1>(var.get<CompoundTag>().begin());
82 break;
83 case Tag::End:
84 res.iter.template emplace<0>(std::addressof(var) + 1);
85 break;
86 default:
87 res.iter.template emplace<0>(std::addressof(var));
88 }
89 return res;
90 }
91
92 static Iterator makeEnd(auto& var) noexcept {
93 Iterator res;
94 switch (var.index()) {
95 case Tag::List:
96 res.iter.template emplace<2>(var.get<ListTag>().end());
97 break;
98 case Tag::Compound:
99 res.iter.template emplace<1>(var.get<CompoundTag>().end());
100 break;
101 default:
102 res.iter.template emplace<0>(std::addressof(var) + 1);
103 }
104 return res;
105 }
106
107 [[nodiscard]] reference operator*() const noexcept {
108 switch (iter.index()) {
109 case 0:
110 return std::get<0>(iter)->get();
111 case 1:
112 return std::get<1>(iter)->second.get();
113 case 2:
114 return *std::get<2>(iter)->get();
115 default:
116 LL_UNREACHABLE;
117 }
118 LL_UNREACHABLE;
119 }
120
121 [[nodiscard]] pointer operator->() const noexcept { return std::addressof(**this); }
122
123 Iterator& operator++() noexcept {
124 std::visit([](auto& val) { ++val; }, iter);
125 return *this;
126 }
127
128 Iterator operator++(int) noexcept {
129 Iterator tmp = *this;
130 ++*this;
131 return tmp;
132 }
133
134 Iterator& operator--() noexcept {
135 std::visit([](auto& val) { --val; }, iter);
136 return *this;
137 }
138
139 Iterator operator--(int) noexcept {
140 Iterator tmp = *this;
141 --*this;
142 return tmp;
143 }
144
145 [[nodiscard]] bool operator==(Iterator const& r) const noexcept { return this->iter == r.iter; }
146 };
147
150
151public:
152 // member variables
153 Variant mTagStorage;
154
155public:
156 // destructor thunk
157 // NOLINTBEGIN
158 MCNAPI void $dtor();
159 // NOLINTEND
160
161public:
162 LLNDAPI static ll::Expected<CompoundTagVariant>
163 parse(std::string_view snbt, optional_ref<size_t> parsedLength = std::nullopt) noexcept;
164
165 [[nodiscard]] constexpr CompoundTagVariant() = default;
166
167 [[nodiscard]] constexpr CompoundTagVariant(CompoundTagVariant&&) = default;
168
169 LL_MAY_CONSTEXPR CompoundTagVariant& operator=(CompoundTagVariant&&) = default;
170
171 [[nodiscard]] constexpr CompoundTagVariant(CompoundTagVariant const&) = default;
172
173 LL_MAY_CONSTEXPR CompoundTagVariant& operator=(CompoundTagVariant const&) = default;
174
175 template <class T>
176 requires(requires(T o) { mTagStorage = std::move(o); })
177 constexpr CompoundTagVariant& operator=(T other) {
178 mTagStorage = std::move(other);
179 return *this;
180 }
181
182 [[nodiscard]] constexpr CompoundTagVariant(std::nullptr_t) {}
183
184 [[nodiscard]] bool operator==(CompoundTagVariant const& other) const { return get() == other.get(); }
185
186 [[nodiscard]] CompoundTagVariant(Variant tag) : mTagStorage(std::move(tag)) {}
187
188 template <class T, class... Args>
189 [[nodiscard]] constexpr CompoundTagVariant(std::in_place_type_t<T>, Args&&... args)
190 : mTagStorage(std::in_place_type<T>, std::forward<Args>(args)...) {}
191
192 [[nodiscard]] constexpr CompoundTagVariant(std::initializer_list<CompoundTag::TagMap::value_type> tagPairs)
193 : mTagStorage(std::in_place_type<CompoundTag>, tagPairs) {}
194
195 [[nodiscard]] CompoundTagVariant(UniqueTagPtr&& tag) {
196 if (!tag) {
197 return;
198 }
199 ::ll::meta::visitIndex<Types::size>(static_cast<size_t>(tag->getId()), [&]<size_t I> {
200 mTagStorage = std::move((Types::get<I>&)*tag);
201 });
202 }
203 [[nodiscard]] CompoundTagVariant(UniqueTagPtr const& tag) : CompoundTagVariant(tag ? tag->copy() : nullptr) {}
204 template <std::derived_from<Tag> T>
205 [[nodiscard]] constexpr CompoundTagVariant(T tag) : mTagStorage(std::move(tag)) {}
206 template <std::integral T>
207 [[nodiscard]] constexpr CompoundTagVariant(T integer) {
208 constexpr size_t size = sizeof(T);
209 if constexpr (size == 1) {
210 mTagStorage = ByteTag{integer};
211 } else if constexpr (size == 2) {
212 mTagStorage = ShortTag{integer};
213 } else if constexpr (size == 4) {
214 mTagStorage = IntTag{integer};
215 } else {
216 mTagStorage = Int64Tag{integer};
217 }
218 }
219 [[nodiscard]] constexpr CompoundTagVariant(std::byte b) : mTagStorage(ByteTag{b}) {}
220
221 [[nodiscard]] constexpr CompoundTagVariant(float f) : mTagStorage(FloatTag{f}) {}
222
223 [[nodiscard]] constexpr CompoundTagVariant(double d) : mTagStorage(DoubleTag{d}) {}
224
225 [[nodiscard]] constexpr CompoundTagVariant(std::string s)
226 : mTagStorage(std::in_place_type<StringTag>, std::move(s)) {}
227
228 [[nodiscard]] constexpr CompoundTagVariant(std::string_view s) : mTagStorage(std::in_place_type<StringTag>, s) {}
229
230 template <size_t N>
231 [[nodiscard]] constexpr CompoundTagVariant(char const (&str)[N])
232 : CompoundTagVariant(std::string_view{str, N - 1}) {}
233
234 [[nodiscard]] iterator begin() noexcept { return iterator::makeBegin(*this); }
235 [[nodiscard]] const_iterator begin() const noexcept { return cbegin(); }
236 [[nodiscard]] const_iterator cbegin() const noexcept { return const_iterator::makeBegin(*this); }
237
238 [[nodiscard]] iterator end() noexcept { return iterator::makeEnd(*this); }
239 [[nodiscard]] const_iterator end() const noexcept { return cend(); }
240 [[nodiscard]] const_iterator cend() const noexcept { return const_iterator::makeEnd(*this); }
241
242 [[nodiscard]] constexpr Tag::Type index() const noexcept { return Tag::Type(mTagStorage.index()); }
243 [[nodiscard]] constexpr Tag::Type getId() const noexcept { return index(); }
244
245 template <std::derived_from<Tag> T>
246 [[nodiscard]] constexpr bool hold() const noexcept {
247 return std::holds_alternative<T>(mTagStorage);
248 }
249 [[nodiscard]] constexpr bool hold(::Tag::Type type) const noexcept { return getId() == type; }
250
251 // consistency with json
252 [[nodiscard]] constexpr bool is_array() const noexcept { return hold(Tag::List); }
253 [[nodiscard]] constexpr bool is_binary() const noexcept { return hold(Tag::ByteArray) || hold(Tag::IntArray); }
254 [[nodiscard]] constexpr bool is_boolean() const noexcept { return hold(Tag::Byte); }
255 [[nodiscard]] constexpr bool is_null() const noexcept { return hold(Tag::End); }
256 [[nodiscard]] constexpr bool is_number_float() const noexcept { return hold(Tag::Float) || hold(Tag::Double); }
257 [[nodiscard]] constexpr bool is_number_integer() const noexcept {
258 return hold(Tag::Byte) || hold(Tag::Short) || hold(Tag::Int) || hold(Tag::Int64);
259 }
260 [[nodiscard]] constexpr bool is_object() const noexcept { return hold(Tag::Compound); }
261 [[nodiscard]] constexpr bool is_string() const noexcept { return hold(Tag::String); }
262 [[nodiscard]] constexpr bool is_number() const noexcept { return is_number_float() || is_number_integer(); }
263 [[nodiscard]] constexpr bool is_primitive() const noexcept {
264 return is_null() || is_string() || is_number() || is_binary();
265 }
266 [[nodiscard]] constexpr bool is_structured() const noexcept { return is_array() || is_object(); }
267
268 [[nodiscard]] constexpr CompoundTag::TagMap const& items() const { return get<CompoundTag>().mTags; }
269 [[nodiscard]] constexpr CompoundTag::TagMap& items() { return get<CompoundTag>().mTags; }
270
271 [[nodiscard]] bool contains(std::string_view key) const noexcept {
272 if (is_object()) {
273 return get<CompoundTag>().contains(key);
274 }
275 return false;
276 }
277
278 [[nodiscard]] bool contains(std::string_view key, Tag::Type type) const noexcept {
279 if (is_object()) {
280 return get<CompoundTag>().contains(key, type);
281 }
282 return false;
283 }
284
285 template <std::derived_from<Tag> T>
286 [[nodiscard]] bool contains(std::string_view key) const noexcept {
287 constexpr size_t idx = Types::index<T>;
288 return contains(key, (Tag::Type)idx);
289 }
290
291 [[nodiscard]] constexpr size_t size() const noexcept {
292 switch (index()) {
293 case Tag::Byte:
294 case Tag::Short:
295 case Tag::Int:
296 case Tag::Int64:
297 case Tag::Float:
298 case Tag::Double:
299 case Tag::String:
300 return 1;
301 case Tag::List:
302 return get<ListTag>().size();
303 case Tag::Compound:
304 return get<CompoundTag>().size();
305 case Tag::IntArray:
306 return get<IntArrayTag>().size();
307 case Tag::ByteArray:
308 return get<ByteArrayTag>().size();
309 case Tag::End:
310 return 0;
311 default:
312 LL_UNREACHABLE;
313 }
314 }
315
316 template <std::derived_from<Tag> T>
317 [[nodiscard]] constexpr T& get() {
318 return std::get<T>(mTagStorage);
319 }
320
321 template <std::derived_from<Tag> T>
322 [[nodiscard]] constexpr T const& get() const {
323 return std::get<T>(mTagStorage);
324 }
325
326 [[nodiscard]] Tag& get() { return reinterpret_cast<Tag&>(mTagStorage); }
327
328 [[nodiscard]] Tag const& get() const { return reinterpret_cast<Tag const&>(mTagStorage); }
329
330 template <std::derived_from<Tag> T>
331 constexpr T& emplace() {
332 return mTagStorage.emplace<T>();
333 }
334
335 [[nodiscard]] UniqueTagPtr& operator[](size_t index) {
336 if (hold(Tag::List)) {
337 return get<ListTag>()[index];
338 } else {
339 throw std::runtime_error("tag not hold an array");
340 }
341 }
342
343 [[nodiscard]] UniqueTagPtr const& operator[](size_t index) const {
344 if (hold(Tag::List)) {
345 return get<ListTag>()[index];
346 } else {
347 throw std::runtime_error("tag not hold an array");
348 }
349 }
350
351 [[nodiscard]] CompoundTagVariant& operator[](std::string_view index) {
352 if (is_null()) {
353 mTagStorage = CompoundTag{};
354 }
355 if (!hold(Tag::Compound)) {
356 throw std::runtime_error("tag not hold an object");
357 }
358 return get<CompoundTag>()[index];
359 }
360
361 [[nodiscard]] CompoundTagVariant const& operator[](std::string_view index) const {
362 if (!hold(Tag::Compound)) {
363 throw std::runtime_error("tag not hold an object");
364 }
365 return get<CompoundTag>()[index];
366 }
367
368 template <size_t N>
369 [[nodiscard]] CompoundTagVariant& operator[](char const (&index)[N]) { // make EDG happy
370 return operator[](std::string_view{index, N - 1});
371 }
372
373 template <size_t N>
374 [[nodiscard]] CompoundTagVariant const& operator[](char const (&index)[N]) const { // make EDG happy
375 return operator[](std::string_view{index, N - 1});
376 }
377
378 [[nodiscard]] UniqueTagPtr toUniqueCopy() const& {
379 return std::visit(
380 [](auto& val) -> std::unique_ptr<Tag> { return std::make_unique<std::decay_t<decltype(val)>>(val); },
381 mTagStorage
382 );
383 }
384
385 [[nodiscard]] UniqueTagPtr toUnique() && {
386 return std::visit(
387 [](auto&& val) -> std::unique_ptr<Tag> {
388 return std::make_unique<std::decay_t<decltype(val)>>(std::move(val));
389 },
390 mTagStorage
391 );
392 }
393
394 LLNDAPI std::string toSnbt(SnbtFormat snbtFormat = SnbtFormat::PrettyFilePrint, uchar indent = 4) const noexcept;
395
396 std::string dump(uchar indent = 4, SnbtFormat snbtFormat = SnbtFormat::PrettyFilePrint) const noexcept {
397 return toSnbt(snbtFormat, indent);
398 }
399
400 void push_back(CompoundTagVariant val) {
401 if (is_null()) {
402 mTagStorage = ListTag{};
403 }
404 if (!hold(Tag::List)) {
405 throw std::runtime_error("tag not hold an array");
406 }
407 get<ListTag>().add(std::move(val).toUnique());
408 }
409
410 template <class T>
411 requires(std::is_arithmetic_v<T> && !ll::traits::is_char_v<T>)
412 [[nodiscard]] constexpr operator T() const {
413 if (is_number()) {
414 return std::visit(
415 [](auto& val) -> T {
416 if constexpr (std::is_convertible_v<std::decay_t<decltype(val)>, T>) {
417 return (T)val;
418 } else {
419 return {};
420 }
421 },
422 mTagStorage
423 );
424 } else {
425 throw std::runtime_error("tag not hold an number");
426 }
427 }
428 [[nodiscard]] operator std::string const&() const { return get<StringTag>(); }
429 [[nodiscard]] operator std::string&() { return get<StringTag>(); }
430 [[nodiscard]] operator std::string&&() && { return std::move(get<StringTag>()); }
431 [[nodiscard]] operator std::string_view() const { return get<StringTag>(); }
432 static CompoundTagVariant object(std::initializer_list<CompoundTag::TagMap::value_type> init = {}) {
433 return CompoundTagVariant{std::in_place_type<CompoundTag>, init};
434 }
435 static CompoundTagVariant array(std::initializer_list<CompoundTagVariant> init = {}) {
436 return CompoundTagVariant{std::in_place_type<ListTag>, init};
437 }
438};
439
440[[nodiscard]] inline auto CompoundTag::begin() noexcept { return mTags.begin(); }
441[[nodiscard]] inline auto CompoundTag::begin() const noexcept { return mTags.begin(); }
442[[nodiscard]] inline auto CompoundTag::end() noexcept { return mTags.end(); }
443[[nodiscard]] inline auto CompoundTag::end() const noexcept { return mTags.end(); }
444[[nodiscard]] inline auto CompoundTag::rbegin() noexcept { return mTags.rbegin(); }
445[[nodiscard]] inline auto CompoundTag::rbegin() const noexcept { return mTags.rbegin(); }
446[[nodiscard]] inline auto CompoundTag::rend() noexcept { return mTags.rend(); }
447[[nodiscard]] inline auto CompoundTag::rend() const noexcept { return mTags.rend(); }
448[[nodiscard]] inline auto CompoundTag::cbegin() const noexcept { return mTags.cbegin(); }
449[[nodiscard]] inline auto CompoundTag::cend() const noexcept { return mTags.cend(); }
450[[nodiscard]] inline auto CompoundTag::crbegin() const noexcept { return mTags.crbegin(); }
451[[nodiscard]] inline auto CompoundTag::crend() const noexcept { return mTags.crend(); }
452inline bool CompoundTag::erase(std::string_view name) {
453 if (auto it = mTags.find(name); it != mTags.end()) {
454 mTags.erase(it);
455 return true;
456 }
457 return false;
458}
459[[nodiscard]] inline CompoundTagVariant& CompoundTag::operator[](std::string_view index) {
460 if (auto it = mTags.find(index); it != mTags.end()) {
461 return it->second;
462 }
463 return mTags[std::string{index}];
464}
465[[nodiscard]] inline CompoundTagVariant const& CompoundTag::operator[](std::string_view index) const {
466 if (auto it = mTags.find(index); it != mTags.end()) {
467 return it->second;
468 }
469 throw std::out_of_range("invalid nbt key");
470}
471[[nodiscard]] inline void CompoundTag::rename(std::string_view name, std::string_view newName) {
472 if (auto it = mTags.find(name); it != mTags.end()) {
473 CompoundTagVariant tmp{std::move(it->second)};
474 mTags.erase(it);
475 mTags.try_emplace(std::string{newName}, std::move(tmp));
476 }
477}
478
479[[nodiscard]] constexpr ListTag::ListTag(std::vector<CompoundTagVariant> tags) {
480 if (tags.empty()) {
481 mType = Tag::End;
482 } else {
483 mType = tags.front().index();
484 reserve(tags.size());
485 for (auto& tag : tags) {
486 emplace_back(std::move(tag).toUnique());
487 }
488 }
489}
490[[nodiscard]] constexpr ListTag::ListTag(std::initializer_list<CompoundTagVariant> tags) {
491 if (tags.size() == 0) {
492 mType = Tag::End;
493 } else {
494 mType = tags.begin()->index();
495 reserve(tags.size());
496 for (auto& tag : tags) {
497 emplace_back(tag.toUniqueCopy());
498 }
499 }
500}
501[[nodiscard]] inline bool operator==(UniqueTagPtr const& l, CompoundTagVariant const& r) {
502 return l ? (*l == r.get()) : false;
503}
504[[nodiscard]] inline bool operator==(CompoundTagVariant const& l, UniqueTagPtr const& r) {
505 return r ? (l.get() == *r) : false;
506}
507
508[[nodiscard]] inline UniqueTagPtr::UniqueTagPtr(CompoundTagVariant&& r) : ptr(std::move(r).toUnique().release()) {}
509
510[[nodiscard]] inline UniqueTagPtr::UniqueTagPtr(CompoundTagVariant const& r) : ptr(r.toUniqueCopy().release()) {}
511
512inline UniqueTagPtr& UniqueTagPtr::operator=(CompoundTagVariant&& r) {
513 reset(std::move(r).toUnique().release());
514 return *this;
515}
516inline UniqueTagPtr& UniqueTagPtr::operator=(CompoundTagVariant const& r) {
517 reset(r.toUniqueCopy().release());
518 return *this;
519}
520
521template <std::derived_from<Tag> T>
522[[nodiscard]] inline T& UniqueTagPtr::get() const {
523 if (hold<T>()) {
524 return *static_cast<T*>(ptr);
525 }
526 throw std::runtime_error("not the expected type");
527}
528[[nodiscard]] inline bool UniqueTagPtr::contains(std::string_view key) const noexcept {
529 if (is_object()) {
530 return get<CompoundTag>().contains(key);
531 }
532 return false;
533}
534[[nodiscard]] inline bool UniqueTagPtr::contains(std::string_view key, Tag::Type type) const noexcept {
535 if (is_object()) {
536 return get<CompoundTag>().contains(key, type);
537 }
538 return false;
539}
540[[nodiscard]] inline size_t UniqueTagPtr::size() const noexcept {
541 switch (index()) {
542 case Tag::Byte:
543 case Tag::Short:
544 case Tag::Int:
545 case Tag::Int64:
546 case Tag::Float:
547 case Tag::Double:
548 case Tag::String:
549 return 1;
550 case Tag::List:
551 return get<ListTag>().size();
552 case Tag::Compound:
553 return get<CompoundTag>().size();
554 case Tag::IntArray:
555 return get<IntArrayTag>().size();
556 case Tag::ByteArray:
557 return get<ByteArrayTag>().size();
558 case Tag::End:
559 return 0;
560 default:
561 LL_UNREACHABLE;
562 }
563}
564[[nodiscard]] inline UniqueTagPtr::operator std::string const&() const { return get<StringTag>(); }
565[[nodiscard]] inline UniqueTagPtr::operator std::string&() & { return get<StringTag>(); }
566[[nodiscard]] inline UniqueTagPtr::operator std::string&&() && { return std::move(get<StringTag>()); }
567[[nodiscard]] inline UniqueTagPtr::operator std::string_view() const { return get<StringTag>(); }
568
569[[nodiscard]] inline UniqueTagPtr& UniqueTagPtr::operator[](size_t index) {
570 if (hold(Tag::List)) {
571 return get<ListTag>()[index];
572 } else {
573 throw std::runtime_error("tag not hold an array");
574 }
575}
576[[nodiscard]] inline UniqueTagPtr const& UniqueTagPtr::operator[](size_t index) const {
577 if (hold(Tag::List)) {
578 return get<ListTag>()[index];
579 } else {
580 throw std::runtime_error("tag not hold an array");
581 }
582}
583[[nodiscard]] inline CompoundTagVariant& UniqueTagPtr::operator[](std::string_view index) {
584 if (is_null()) {
585 emplace<CompoundTag>();
586 }
587 if (!hold(Tag::Compound)) {
588 throw std::runtime_error("tag not hold an object");
589 }
590 return get<CompoundTag>()[index];
591}
592[[nodiscard]] inline CompoundTagVariant const& UniqueTagPtr::operator[](std::string_view index) const {
593 if (!hold(Tag::Compound)) {
594 throw std::runtime_error("tag not hold an object");
595 }
596 return get<CompoundTag>()[index];
597}
598template <class T>
599 requires(std::is_arithmetic_v<T> && !ll::traits::is_char_v<T>)
600[[nodiscard]] inline UniqueTagPtr::operator T() const {
601 if (is_number()) {
602 return ll::meta::visitIndex<CompoundTagVariant::Types::size>((size_t)getId(), [&]<size_t I>() -> T {
603 auto& val = *static_cast<CompoundTagVariant::Types::get<I>*>(ptr);
604 if constexpr (std::is_convertible_v<std::decay_t<decltype(val)>, T>) {
605 return (T)val;
606 } else {
607 return {};
608 }
609 });
610 } else {
611 throw std::runtime_error("tag not hold an number");
612 }
613}
Definition ByteArrayTag.h:9
Definition ByteTag.h:9
Definition CompoundTagVariant.h:60
Definition CompoundTagVariant.h:40
MCAPI void $dtor()
Definition CompoundTag.h:13
Definition DoubleTag.h:9
Definition EndTag.h:9
Definition FloatTag.h:9
Definition Int64Tag.h:9
Definition IntArrayTag.h:9
Definition IntTag.h:9
Definition ListTag.h:12
Definition ShortTag.h:9
Definition StringTag.h:9
Definition Tag.h:39
Definition UniqueTagPtr.h:22
Definition Meta.h:197
Definition optional_ref.h:10
STL namespace.