chenjunfu2-nbt-cpp v2.1.5
一个基于CPP20的NBT(Named Binary Tag)库
载入中...
搜索中...
未找到
NBT_Compound.hpp
浏览该文件的文档.
1#pragma once
2
3#include <vector>
4#include <unordered_map>
5#include <compare>
6#include <type_traits>
7#include <initializer_list>
8
9#include "NBT_Type.hpp"
10
13
14class NBT_Reader;
15class NBT_Writer;
16class NBT_Helper;
17
21template<typename Compound>
22class NBT_Compound :protected Compound//Compound is Map
23{
24 friend class NBT_Reader;
25 friend class NBT_Writer;
26 friend class NBT_Helper;
27
28public:
30 using Super = Compound;
31
36
37 using Hasher = typename Compound::hasher;
38 using Key_Type = typename Compound::key_type;
39 using Mapped_Type = typename Compound::mapped_type;
40 using Key_Equal = typename Compound::key_equal;
41 using Value_Type = typename Compound::value_type;
42 using Allocator_Type = typename Compound::allocator_type;
43 using Size_Type = typename Compound::size_type;
44 using Difference_Type = typename Compound::difference_type;
45 using Pointer = typename Compound::pointer;
46 using Const_Pointer = typename Compound::const_pointer;
47 using Reference = typename Compound::reference;
48 using Const_Reference = typename Compound::const_reference;
49 using Iterator = typename Compound::iterator;
50 using Const_Iterator = typename Compound::const_iterator;
51 using Local_Iterator = typename Compound::local_iterator;
52 using Const_Local_Iterator = typename Compound::const_local_iterator;
53 using Node_Type = typename Compound::node_type;
54 using Insert_Return_Type = typename Compound::insert_return_type;
55
57
58public:
59 //完美转发、初始化列表代理构造
60
65 template<typename... Args>
66 NBT_Compound(Args&&... args) : Compound(std::forward<Args>(args)...)
67 {}
68
72 NBT_Compound(std::initializer_list<typename Compound::value_type> init) : Compound(init)
73 {}
74
76 NBT_Compound(void) = default;
78 ~NBT_Compound(void) = default;
79
82 NBT_Compound(NBT_Compound &&_Move) noexcept :Compound(std::move(_Move))
83 {}
84
87 NBT_Compound(const NBT_Compound &_Copy) :Compound(_Copy)
88 {}
89
92 const Compound &GetData(void) const noexcept
93 {
94 return *this;
95 }
96
99 Compound &GetData(void) noexcept
100 {
101 return *this;
102 }
103
108 {
109 Compound::operator=(std::move(_Move));
110 return *this;
111 }
112
117 {
118 Compound::operator=(_Copy);
119 return *this;
120 }
121
126 bool operator==(const NBT_Compound &_Right) const noexcept
127 {
128 return (const Compound &)*this == (const Compound &)_Right;
129 }
130
135 bool operator!=(const NBT_Compound &_Right) const noexcept
136 {
137 return (const Compound &)*this != (const Compound &)_Right;
138 }
139
150 std::partial_ordering operator<=>(const NBT_Compound &_Right) const noexcept
151 {
152 if (auto _cmpSize = Compound::size() <=> _Right.size(); _cmpSize != 0)
153 {
154 return _cmpSize;
155 }
156
157 //数量相等,比较数据的排序
158 const auto _lSort = this->KeySortIt();
159 const auto _rSort = _Right.KeySortIt();
160 typename Compound::size_type _Size = Compound::size();
161
162 for (typename Compound::size_type _i = 0; _i < _Size; ++_i)
163 {
164 const auto &_lIt = _lSort[_i];
165 const auto &_rIt = _rSort[_i];
166
167 //首先比较名称,如果不同则返回
168 if (auto _cmpKey = _lIt->first <=> _rIt->first; _cmpKey != 0)
169 {
170 return _cmpKey;
171 }
172
173 //然后比较值,如果不同则返回
174 if (auto _cmpVal = _lIt->second <=> _rIt->second; _cmpVal != 0)
175 {
176 return _cmpVal;
177 }
178 }
179
180 //前面都没有返回,那么所有元素都相等
181 return std::partial_ordering::equivalent;
182 }
183
191 template<bool bAscending = true>
192 std::vector<typename Compound::iterator> KeySortIt(void)
193 {
194 std::vector<typename Compound::iterator> listSortIt;
195 listSortIt.reserve(Compound::size());
196 for (auto it = Compound::begin(); it != Compound::end(); ++it)
197 {
198 listSortIt.push_back(it);
199 }
200
201 std::sort(listSortIt.begin(), listSortIt.end(),
202 [](const auto &l, const auto &r) -> bool
203 {
204 if constexpr (bAscending)
205 {
206 return l->first < r->first;
207 }
208 else
209 {
210 return l->first > r->first;
211 }
212 }
213 );
214
215 return listSortIt;
216 }
217
225 template<bool bAscending = true>
226 std::vector<typename Compound::const_iterator> KeySortIt(void) const
227 {
228 std::vector<typename Compound::const_iterator> listSortIt;
229 listSortIt.reserve(Compound::size());
230 for (auto it = Compound::cbegin(); it != Compound::cend(); ++it)
231 {
232 listSortIt.push_back(it);
233 }
234
235 std::sort(listSortIt.begin(), listSortIt.end(),
236 [](const auto &l, const auto &r) -> bool
237 {
238 if constexpr (bAscending)
239 {
240 return l->first < r->first;
241 }
242 else
243 {
244 return l->first > r->first;
245 }
246 }
247 );
248
249 return listSortIt;
250 }
251
255
256 using Compound::begin;
257 using Compound::end;
258 using Compound::cbegin;
259 using Compound::cend;
260 using Compound::operator[];
261
263
264 //简化map查询
265
271 template <NBT_String_Helper::Is_NBT_String_Or_View K>
272 typename Compound::mapped_type &Get(const K &sTagName)
273 {
274 auto find = Compound::find(sTagName);//cpp26起at才有is_transparent重载,20使用find+异常替代
275 if (find == Compound::end())
276 {
277 throw std::out_of_range("invalid NBT_Compound::Get key");
278 }
279 return find->second;
280 }
281
287 template <NBT_String_Helper::Is_NBT_String_Or_View K>
288 const typename Compound::mapped_type &Get(const K &sTagName) const
289 {
290 auto find = Compound::find(sTagName);//cpp26起at才有is_transparent重载,20使用find+异常替代
291 if (find == Compound::end())
292 {
293 throw std::out_of_range("invalid NBT_Compound::Get key");
294 }
295 return find->second;
296 }
297
303 template <NBT_String_Helper::Is_NBT_String_Or_View K>
304 typename Compound::mapped_type *Has(const K &sTagName) noexcept
305 {
306 auto find = Compound::find(sTagName);
307 return find == Compound::end()
308 ? nullptr
309 : &(find->second);
310 }
311
317 template <NBT_String_Helper::Is_NBT_String_Or_View K>
318 const typename Compound::mapped_type *Has(const K &sTagName) const noexcept
319 {
320 auto find = Compound::find(sTagName);
321 return find == Compound::end()
322 ? nullptr
323 : &(find->second);
324 }
325
326 //简化map插入
327 //使用完美转发,不丢失引用、右值信息
328
337 template <typename K, typename V>
338 requires (NBT_String_Helper::Is_NBT_String_Or_View<K> || std::constructible_from<typename Compound::key_type, K &&>) &&
339 std::constructible_from<typename Compound::mapped_type, V &&>
340 std::pair<typename Compound::iterator, bool> Put(K &&sTagName, V &&vTagVal)
341 {
342 return Compound::insert_or_assign(std::forward<K>(sTagName), std::forward<V>(vTagVal));
343 }
344
353 template <typename K, typename V>
354 requires (NBT_String_Helper::Is_NBT_String_Or_View<K> || std::constructible_from<typename Compound::key_type, K &&>) &&
355 std::constructible_from<typename Compound::mapped_type, V &&>
356 std::pair<typename Compound::iterator, bool> TryPut(K &&sTagName, V &&vTagVal)
357 {
358 return Compound::try_emplace(std::forward<K>(sTagName), std::forward<V>(vTagVal));
359 }
360
365 template <NBT_String_Helper::Is_NBT_String_Or_View K>
366 bool Remove(const K &sTagName)
367 {
368 return Compound::erase(sTagName) != 0;//返回1即为成功,否则为0,标准库:返回值为删除的元素数(0 或 1)。
369 }
370
373 void Clear(void)
374 {
375 Compound::clear();
376 }
377
380 bool Empty(void) const noexcept
381 {
382 return Compound::empty();
383 }
384
387 typename Compound::size_type Size(void) const noexcept
388 {
389 return Compound::size();
390 }
391
396 void Merge(const NBT_Compound &_Copy)
397 {
398 Compound::merge(_Copy);
399 }
400
405 void Merge(NBT_Compound &&_Move)
406 {
407 Compound::merge(std::move(_Move));
408 }
409
414 template <NBT_String_Helper::Is_NBT_String_Or_View K>
415 bool Contains(const K &sTagName) const noexcept
416 {
417 return Compound::contains(sTagName);
418 }
419
425 template<typename Predicate>
426 bool ContainsIf(Predicate pred) const noexcept
427 {
428 return std::find_if(Compound::begin(), Compound::end(), pred) != Compound::end();
429 }
430
431
432//针对每种类型生成一个方便的函数
433//通过宏定义批量生成
434
438#define TYPE_GET_FUNC(type)\
439\
446template <NBT_String_Helper::Is_NBT_String_Or_View K>\
447bool Contains##type(const K &sTagName) const noexcept\
448{\
449 auto *p = Has(sTagName);\
450 return p != nullptr && p->Is##type();\
451}\
452\
453\
460template <NBT_String_Helper::Is_NBT_String_Or_View K>\
461const typename NBT_Type::type &Get##type(const K & sTagName) const\
462{\
463 return Get(sTagName).Get##type();\
464}\
465\
466\
473template <NBT_String_Helper::Is_NBT_String_Or_View K>\
474typename NBT_Type::type &Get##type(const K & sTagName)\
475{\
476 return Get(sTagName).Get##type();\
477}\
478\
479
480\
486template <NBT_String_Helper::Is_NBT_String_Or_View K>\
487const typename NBT_Type::type *Has##type(const K & sTagName) const noexcept\
489 auto *p = Has(sTagName);\
490 return p != nullptr\
491 ? p->GetIf##type()\
492 : nullptr;\
502template <NBT_String_Helper::Is_NBT_String_Or_View K>\
503typename NBT_Type::type *Has##type(const K & sTagName) noexcept\
504{\
505 auto *p = Has(sTagName);\
506 return p != nullptr\
507 ? p->GetIf##type()\
508 : nullptr;\
509}
510
516
527 TYPE_GET_FUNC(String);
528 TYPE_GET_FUNC(List);
529 TYPE_GET_FUNC(Compound);
530
532
533#undef TYPE_GET_FUNC
534
538#define TYPE_PUT_FUNC(type)\
539
540\
548template <typename K>\
549requires NBT_String_Helper::Is_NBT_String_Or_View<K> || std::constructible_from<typename Compound::key_type, K &&>\
550std::pair<typename Compound::iterator, bool> Put##type(K &&sTagName, const typename NBT_Type::type &vTagVal)\
552 return Put(std::forward<K>(sTagName), vTagVal);\
564template <typename K>\
565requires NBT_String_Helper::Is_NBT_String_Or_View<K> || std::constructible_from<typename Compound::key_type, K &&>\
566std::pair<typename Compound::iterator, bool> Put##type(K &&sTagName, typename NBT_Type::type &&vTagVal)\
567{\
568 return Put(std::forward<K>(sTagName), std::move(vTagVal));\
569}\
570\
571\
580template <typename K>\
581requires NBT_String_Helper::Is_NBT_String_Or_View<K> || std::constructible_from<typename Compound::key_type, K &&>\
582std::pair<typename Compound::iterator, bool> TryPut##type(K &&sTagName, const typename NBT_Type::type &vTagVal)\
583{\
584 return TryPut(std::forward<K>(sTagName), vTagVal);\
585}\
586\
587\
596template <typename K>\
597requires NBT_String_Helper::Is_NBT_String_Or_View<K> || std::constructible_from<typename Compound::key_type, K &&>\
598std::pair<typename Compound::iterator, bool> TryPut##type(K &&sTagName, typename NBT_Type::type &&vTagVal)\
599{\
600 return TryPut(std::forward<K>(sTagName), std::move(vTagVal));\
601}
602
607
618 TYPE_PUT_FUNC(String);
619 TYPE_PUT_FUNC(List);
620 TYPE_PUT_FUNC(Compound);
621
623
624#undef TYPE_PUT_FUNC
625};
#define TYPE_PUT_FUNC(type)
不同类型名接口生成宏
定义 NBT_Compound.hpp:508
#define TYPE_GET_FUNC(type)
不同类型名接口生成宏
定义 NBT_Compound.hpp:438
@ Int
对应NBT_Type::Int
定义 NBT_TAG.hpp:21
@ Float
对应NBT_Type::Float
定义 NBT_TAG.hpp:23
@ Compound
对应NBT_Type::Compound
定义 NBT_TAG.hpp:28
@ ByteArray
对应NBT_Type::ByteArray
定义 NBT_TAG.hpp:25
@ Short
对应NBT_Type::Short
定义 NBT_TAG.hpp:20
@ Long
对应NBT_Type::Long
定义 NBT_TAG.hpp:22
@ End
对应NBT_Type::End
定义 NBT_TAG.hpp:18
@ LongArray
对应NBT_Type::LongArray
定义 NBT_TAG.hpp:30
@ Byte
对应NBT_Type::Byte
定义 NBT_TAG.hpp:19
@ IntArray
对应NBT_Type::IntArray
定义 NBT_TAG.hpp:29
@ Double
对应NBT_Type::Double
定义 NBT_TAG.hpp:24
NBT所有类型定义与类型处理工具集
NBT_Compound(std::initializer_list< typename Compound::value_type > init)
初始化列表构造函数
定义 NBT_Compound.hpp:72
typename Compound::const_pointer Const_Pointer
标准库容器公开类型映射
定义 NBT_Compound.hpp:46
std::partial_ordering operator<=>(const NBT_Compound &_Right) const noexcept
三路比较运算符
定义 NBT_Compound.hpp:150
void Clear(void)
清空所有标签
定义 NBT_Compound.hpp:373
bool operator!=(const NBT_Compound &_Right) const noexcept
不等比较运算符
定义 NBT_Compound.hpp:135
typename Compound::mapped_type Mapped_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:39
NBT_Compound(void)=default
默认构造函数
Compound Super
父类类型
定义 NBT_Compound.hpp:30
std::vector< typename Compound::iterator > KeySortIt(void)
获取按键名排序的迭代器向量(非常量版本)
定义 NBT_Compound.hpp:192
NBT_Compound(NBT_Compound &&_Move) noexcept
移动构造函数
定义 NBT_Compound.hpp:82
Compound::mapped_type & Get(const K &sTagName)
根据标签名获取对应的NBT值
定义 NBT_Compound.hpp:272
NBT_Compound & operator=(const NBT_Compound &_Copy)
拷贝赋值运算符
定义 NBT_Compound.hpp:116
NBT_Compound & operator=(NBT_Compound &&_Move) noexcept
移动赋值运算符
定义 NBT_Compound.hpp:107
std::vector< typename Compound::const_iterator > KeySortIt(void) const
获取按键名排序的常量迭代器向量(常量版本)
定义 NBT_Compound.hpp:226
typename Compound::allocator_type Allocator_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:42
typename Compound::key_equal Key_Equal
标准库容器公开类型映射
定义 NBT_Compound.hpp:40
typename Compound::const_local_iterator Const_Local_Iterator
标准库容器公开类型映射
定义 NBT_Compound.hpp:52
void Merge(NBT_Compound &&_Move)
合并另一个NBT_Compound的内容(移动)
定义 NBT_Compound.hpp:405
Compound::mapped_type * Has(const K &sTagName) noexcept
搜索标签是否存在
定义 NBT_Compound.hpp:304
typename Compound::value_type Value_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:41
const Compound & GetData(void) const noexcept
获取底层容器数据的常量引用
定义 NBT_Compound.hpp:92
const Compound::mapped_type * Has(const K &sTagName) const noexcept
搜索标签是否存在(常量版本)
定义 NBT_Compound.hpp:318
bool Remove(const K &sTagName)
删除指定标签
定义 NBT_Compound.hpp:366
const Compound::mapped_type & Get(const K &sTagName) const
根据标签名获取对应的NBT值(常量版本)
定义 NBT_Compound.hpp:288
typename Compound::size_type Size_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:43
typename Compound::iterator Iterator
标准库容器公开类型映射
定义 NBT_Compound.hpp:49
typename Compound::const_reference Const_Reference
标准库容器公开类型映射
定义 NBT_Compound.hpp:48
bool Empty(void) const noexcept
检查容器是否为空
定义 NBT_Compound.hpp:380
Compound & GetData(void) noexcept
获取底层容器数据的引用
定义 NBT_Compound.hpp:99
NBT_Compound(const NBT_Compound &_Copy)
拷贝构造函数
定义 NBT_Compound.hpp:87
typename Compound::insert_return_type Insert_Return_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:54
typename Compound::key_type Key_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:38
bool Contains(const K &sTagName) const noexcept
检查是否包含指定标签
定义 NBT_Compound.hpp:415
typename Compound::const_iterator Const_Iterator
标准库容器公开类型映射
定义 NBT_Compound.hpp:50
typename Compound::hasher Hasher
标准库容器公开类型映射
定义 NBT_Compound.hpp:37
typename Compound::local_iterator Local_Iterator
标准库容器公开类型映射
定义 NBT_Compound.hpp:51
bool operator==(const NBT_Compound &_Right) const noexcept
相等比较运算符
定义 NBT_Compound.hpp:126
NBT_Compound(Args &&... args)
完美转发构造函数
定义 NBT_Compound.hpp:66
~NBT_Compound(void)=default
默认析构函数
bool ContainsIf(Predicate pred) const noexcept
使用谓词检查是否存在满足条件的元素
定义 NBT_Compound.hpp:426
typename Compound::difference_type Difference_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:44
Compound::size_type Size(void) const noexcept
获取容器中元素的数量
定义 NBT_Compound.hpp:387
typename Compound::reference Reference
标准库容器公开类型映射
定义 NBT_Compound.hpp:47
void Merge(const NBT_Compound &_Copy)
合并另一个NBT_Compound的内容(拷贝)
定义 NBT_Compound.hpp:396
std::pair< typename Compound::iterator, bool > TryPut(K &&sTagName, V &&vTagVal)
原位构造键值对
定义 NBT_Compound.hpp:356
typename Compound::pointer Pointer
标准库容器公开类型映射
定义 NBT_Compound.hpp:45
std::pair< typename Compound::iterator, bool > Put(K &&sTagName, V &&vTagVal)
插入或替换键值对
定义 NBT_Compound.hpp:340
typename Compound::node_type Node_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:53
用于格式化打印、序列化、计算哈希等功能
定义 NBT_Helper.hpp:25
这个类用于提供从NBT二进制流读取到NBT_Type::Compound对象的反序列化功能
定义 NBT_Reader.hpp:23
这个类用于提供从NBT_Type::Compound对象写出到NBT二进制流的序列化功能
定义 NBT_Writer.hpp:23
约束类型 T 去除 cv-ref 限定后必须是 NBT_String 或其对应的 View
定义 NBT_String.hpp:544
在std命名空间中添加类的默认hash特化以便unordered_map等容器自动获取
定义 NBT_String.hpp:477