LeviLamina
Loading...
Searching...
No Matches
UniqueTagPtr.h
1#pragma once
2
3#include "mc/deps/nbt/Tag.h"
4
5#include "ll/api/Expected.h"
6#include "ll/api/base/Concepts.h"
7#include "ll/api/base/Meta.h"
8
9class ByteTag;
10class ShortTag;
11class IntTag;
12class Int64Tag;
13class FloatTag;
14class DoubleTag;
15class ByteArrayTag;
16class StringTag;
17class ListTag;
18class CompoundTag;
19class IntArrayTag;
21
22class UniqueTagPtr {
23 Tag* ptr{};
24
25
26 using Types = ::ll::meta::TypeList<
27 EndTag,
28 ByteTag,
30 IntTag,
36 ListTag,
39
40public:
41 using string_t = std::string;
42
43 [[nodiscard]] LL_CONSTEXPR23 UniqueTagPtr() noexcept {}
44
45 [[nodiscard]] LL_CONSTEXPR23 UniqueTagPtr(nullptr_t) noexcept {}
46
47 [[nodiscard]] LL_CONSTEXPR23 explicit UniqueTagPtr(Tag* p) noexcept : ptr(p) {}
48
49 [[nodiscard]] LL_CONSTEXPR23 UniqueTagPtr(std::unique_ptr<Tag>&& ptr) noexcept : ptr(ptr.release()) {}
50
51 [[nodiscard]] LL_CONSTEXPR23 UniqueTagPtr(UniqueTagPtr&& r) noexcept : ptr(r.release()) {}
52
53 [[nodiscard]] LL_CONSTEXPR23 UniqueTagPtr(UniqueTagPtr const& r) : ptr(r ? (r->copy().release()) : nullptr) {}
54
55 [[nodiscard]] UniqueTagPtr(CompoundTagVariant&& r);
56 [[nodiscard]] UniqueTagPtr(CompoundTagVariant const& r);
57
58 UniqueTagPtr& operator=(CompoundTagVariant&& r);
59 UniqueTagPtr& operator=(CompoundTagVariant const& r);
60
61 LL_CONSTEXPR23 UniqueTagPtr& operator=(nullptr_t) noexcept {
62 reset();
63 return *this;
64 }
65
66 LL_CONSTEXPR23 UniqueTagPtr& operator=(std::unique_ptr<Tag>&& r) noexcept {
67 reset(r.release());
68 return *this;
69 }
70
71 LL_CONSTEXPR23 UniqueTagPtr& operator=(UniqueTagPtr&& r) noexcept {
72 reset(r.release());
73 return *this;
74 }
75
76 LL_CONSTEXPR23 UniqueTagPtr& operator=(UniqueTagPtr const& r) {
77 if (r && &r != this) ptr = r->copy().release();
78 return *this;
79 }
80 LL_CONSTEXPR23 void swap(UniqueTagPtr& r) noexcept { std::swap(ptr, r.ptr); }
81
82 LL_CONSTEXPR23 ~UniqueTagPtr() noexcept { delete ptr; }
83
84 [[nodiscard]] LL_CONSTEXPR23 Tag& operator*() const noexcept { return *ptr; }
85
86 [[nodiscard]] LL_CONSTEXPR23 Tag* operator->() const noexcept { return ptr; }
87
88 [[nodiscard]] LL_CONSTEXPR23 Tag* get() const noexcept { return ptr; }
89
90 LL_CONSTEXPR23 explicit operator bool() const noexcept { return static_cast<bool>(ptr); }
91
92 LL_CONSTEXPR23 operator std::unique_ptr<Tag>() && noexcept { return std::unique_ptr<Tag>{release()}; }
93
94 LL_CONSTEXPR23 operator std::unique_ptr<Tag>() const& noexcept { return ptr ? ptr->copy() : nullptr; }
95
96 LL_CONSTEXPR23 Tag* release() noexcept { return std::exchange(ptr, nullptr); }
97
98 LL_CONSTEXPR23 void reset(Tag* p = nullptr) noexcept {
99 Tag* old = std::exchange(ptr, p);
100 delete old;
101 }
102
103 [[nodiscard]] UniqueTagPtr& operator[](size_t index);
104 [[nodiscard]] UniqueTagPtr const& operator[](size_t index) const;
105 [[nodiscard]] CompoundTagVariant& operator[](std::string_view index);
106 [[nodiscard]] CompoundTagVariant const& operator[](std::string_view index) const;
107 template <size_t N>
108 [[nodiscard]] CompoundTagVariant& operator[](char const (&index)[N]) { // make EDG happy
109 return operator[](std::string_view{index});
110 }
111 template <size_t N>
112 [[nodiscard]] CompoundTagVariant const& operator[](char const (&index)[N]) const { // make EDG happy
113 return operator[](std::string_view{index});
114 }
115
116public:
117 [[nodiscard]] std::unique_ptr<Tag> copy() const { return ptr ? ptr->copy() : nullptr; }
118
119 [[nodiscard]] ::Tag::Type index() const { return ptr ? ptr->getId() : ::Tag::End; }
120 [[nodiscard]] Tag::Type getId() const noexcept { return index(); }
121
122 [[nodiscard]] inline bool operator==(UniqueTagPtr const& r) const {
123 return (ptr == r.get()) || (ptr && r && *ptr == *r);
124 }
125 template <std::derived_from<Tag> T>
126 [[nodiscard]] bool hold() const noexcept {
127 return ptr && (Types::index<T> == (size_t)getId());
128 }
129 [[nodiscard]] bool hold(::Tag::Type type) const noexcept { return ptr && (getId() == type); }
130
131 // consistency with json
132 [[nodiscard]] bool is_array() const noexcept { return hold(Tag::List); }
133 [[nodiscard]] bool is_binary() const noexcept { return hold(Tag::ByteArray) || hold(Tag::IntArray); }
134 [[nodiscard]] bool is_boolean() const noexcept { return hold(Tag::Byte); }
135 [[nodiscard]] bool is_null() const noexcept { return hold(Tag::End); }
136 [[nodiscard]] bool is_number_float() const noexcept { return hold(Tag::Float) || hold(Tag::Double); }
137 [[nodiscard]] bool is_number_integer() const noexcept {
138 return hold(Tag::Byte) || hold(Tag::Short) || hold(Tag::Int) || hold(Tag::Int64);
139 }
140 [[nodiscard]] bool is_number_signed() const noexcept { return is_number_integer(); }
141 [[nodiscard]] bool is_number_unsigned() const noexcept { return false; }
142 [[nodiscard]] bool is_object() const noexcept { return hold(Tag::Compound); }
143 [[nodiscard]] bool is_string() const noexcept { return hold(Tag::String); }
144 [[nodiscard]] bool is_number() const noexcept { return is_number_float() || is_number_integer(); }
145 [[nodiscard]] bool is_primitive() const noexcept { return is_null() || is_string() || is_number() || is_binary(); }
146 [[nodiscard]] bool is_structured() const noexcept { return is_array() || is_object(); }
147 [[nodiscard]] std::string_view type_name() const noexcept {
148 if (is_null()) return "null";
149 if (is_object()) return "object";
150 if (is_array()) return "array";
151 if (is_string()) return "string";
152 if (is_boolean()) return "boolean";
153 if (is_number()) return "number";
154 if (is_binary()) return "binary";
155 return "unknown";
156 }
157
158 [[nodiscard]] std::string
159 toSnbt(SnbtFormat snbtFormat = SnbtFormat::PrettyFilePrint, uchar indent = 4) const noexcept {
160 return ptr ? ptr->toSnbt(snbtFormat, indent) : "";
161 }
162 template <std::derived_from<Tag> T>
163 T& emplace() {
164 auto newptr = new T();
165 reset(newptr);
166 return *newptr;
167 }
168 template <std::derived_from<Tag> T>
169 [[nodiscard]] bool contains(std::string_view key) const noexcept {
170 return contains(key, (Tag::Type)Types::index<T>);
171 }
172
173public:
174 template <std::derived_from<Tag> T>
175 [[nodiscard]] T& get() const;
176
177 [[nodiscard]] bool contains(std::string_view key) const noexcept;
178 [[nodiscard]] bool contains(std::string_view key, Tag::Type type) const noexcept;
179 [[nodiscard]] size_t size() const noexcept;
180
181 [[nodiscard]] operator std::string const&() const;
182 [[nodiscard]] operator std::string&() &;
183 [[nodiscard]] operator std::string&&() &&;
184 [[nodiscard]] operator std::string_view() const;
185
186 template <class Ref>
187 [[nodiscard]] Ref get_ref() &
188 requires(std::same_as<Ref, string_t&>)
189 {
190 return static_cast<string_t&>(*this);
191 }
192
193 template <class Ref>
194 [[nodiscard]] Ref get_ref() const&
195 requires(std::same_as<Ref, string_t const&>)
196 {
197 return static_cast<string_t const&>(*this);
198 }
199
200 template <class T>
201 requires(std::is_arithmetic_v<T> && !ll::traits::is_char_v<T>)
202 [[nodiscard]] operator T() const;
203};
Definition ByteArrayTag.h:9
Definition ByteTag.h:15
Definition CompoundTagVariant.h:28
Definition CompoundTag.h:18
Definition DoubleTag.h:9
Definition EndTag.h:9
Definition FloatTag.h:15
Definition Int64Tag.h:9
Definition IntArrayTag.h:9
Definition IntTag.h:15
Definition ListTag.h:19
Definition ShortTag.h:9
Definition StringTag.h:15
Definition Tag.h:42
Definition Meta.h:197