41 using string_t = std::string;
43 [[nodiscard]] LL_CONSTEXPR23 UniqueTagPtr()
noexcept {}
45 [[nodiscard]] LL_CONSTEXPR23 UniqueTagPtr(nullptr_t)
noexcept {}
47 [[nodiscard]] LL_CONSTEXPR23
explicit UniqueTagPtr(
Tag* p) noexcept : ptr(p) {}
49 [[nodiscard]] LL_CONSTEXPR23 UniqueTagPtr(std::unique_ptr<Tag>&& ptr) noexcept : ptr(ptr.release()) {}
51 [[nodiscard]] LL_CONSTEXPR23 UniqueTagPtr(UniqueTagPtr&& r) noexcept : ptr(r.release()) {}
53 [[nodiscard]] LL_CONSTEXPR23 UniqueTagPtr(UniqueTagPtr
const& r) : ptr(r ? (r->copy().release()) :
nullptr) {}
61 LL_CONSTEXPR23 UniqueTagPtr& operator=(nullptr_t)
noexcept {
66 LL_CONSTEXPR23 UniqueTagPtr& operator=(std::unique_ptr<Tag>&& r)
noexcept {
71 LL_CONSTEXPR23 UniqueTagPtr& operator=(UniqueTagPtr&& r)
noexcept {
76 LL_CONSTEXPR23 UniqueTagPtr& operator=(UniqueTagPtr
const& r) {
77 if (r && &r !=
this) ptr = r->copy().release();
80 LL_CONSTEXPR23
void swap(UniqueTagPtr& r)
noexcept { std::swap(ptr, r.ptr); }
82 LL_CONSTEXPR23 ~UniqueTagPtr()
noexcept {
delete ptr; }
84 [[nodiscard]] LL_CONSTEXPR23
Tag& operator*()
const noexcept {
return *ptr; }
86 [[nodiscard]] LL_CONSTEXPR23
Tag* operator->()
const noexcept {
return ptr; }
88 [[nodiscard]] LL_CONSTEXPR23
Tag* get()
const noexcept {
return ptr; }
90 LL_CONSTEXPR23
explicit operator bool()
const noexcept {
return static_cast<bool>(ptr); }
92 LL_CONSTEXPR23
operator std::unique_ptr<Tag>() &&
noexcept {
return std::unique_ptr<Tag>{release()}; }
94 LL_CONSTEXPR23
operator std::unique_ptr<Tag>()
const&
noexcept {
return ptr ? ptr->copy() :
nullptr; }
96 LL_CONSTEXPR23
Tag* release()
noexcept {
return std::exchange(ptr,
nullptr); }
98 LL_CONSTEXPR23
void reset(
Tag* p =
nullptr)
noexcept {
99 Tag* old = std::exchange(ptr, p);
103 [[nodiscard]] UniqueTagPtr& operator[](
size_t index);
104 [[nodiscard]] UniqueTagPtr
const& operator[](
size_t index)
const;
109 return operator[](std::string_view{index});
113 return operator[](std::string_view{index});
117 [[nodiscard]] std::unique_ptr<Tag> copy()
const {
return ptr ? ptr->copy() :
nullptr; }
119 [[nodiscard]] ::Tag::Type index()
const {
return ptr ? ptr->getId() : ::Tag::End; }
120 [[nodiscard]] Tag::Type getId()
const noexcept {
return index(); }
122 [[nodiscard]]
inline bool operator==(UniqueTagPtr
const& r)
const {
123 return (ptr == r.get()) || (ptr && r && *ptr == *r);
125 template <std::derived_from<Tag> T>
126 [[nodiscard]]
bool hold()
const noexcept {
127 return ptr && (Types::index<T> == (size_t)getId());
129 [[nodiscard]]
bool hold(::Tag::Type type)
const noexcept {
return ptr && (getId() == type); }
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);
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";
158 [[nodiscard]] std::string
159 toSnbt(SnbtFormat snbtFormat = SnbtFormat::PrettyFilePrint, uchar indent = 4)
const noexcept {
160 return ptr ? ptr->toSnbt(snbtFormat, indent) :
"";
162 template <std::derived_from<Tag> T>
164 auto newptr =
new T();
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>);
174 template <std::derived_from<Tag> T>
175 [[nodiscard]] T& get()
const;
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;
181 [[nodiscard]]
operator std::string
const&()
const;
182 [[nodiscard]]
operator std::string&() &;
183 [[nodiscard]]
operator std::string&&() &&;
184 [[nodiscard]]
operator std::string_view()
const;
187 [[nodiscard]] Ref get_ref() &
188 requires(std::same_as<Ref, string_t&>)
190 return static_cast<string_t&
>(*this);
194 [[nodiscard]] Ref get_ref()
const&
195 requires(std::same_as<Ref, string_t const&>)
197 return static_cast<string_t const&
>(*this);
201 requires(std::is_arithmetic_v<T> && !ll::traits::is_char_v<T>)
202 [[nodiscard]]
operator T()
const;