chenjunfu2-nbt-cpp v2.1.3
一个基于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:
33
34 using Hasher = typename Compound::hasher;
35 using Key_Type = typename Compound::key_type;
36 using Mapped_Type = typename Compound::mapped_type;
37 using Key_Equal = typename Compound::key_equal;
38 using Value_Type = typename Compound::value_type;
39 using Allocator_Type = typename Compound::allocator_type;
40 using Size_Type = typename Compound::size_type;
41 using Difference_Type = typename Compound::difference_type;
42 using Pointer = typename Compound::pointer;
43 using Const_Pointer = typename Compound::const_pointer;
44 using Reference = typename Compound::reference;
45 using Const_Reference = typename Compound::const_reference;
46 using Iterator = typename Compound::iterator;
47 using Const_Iterator = typename Compound::const_iterator;
48 using Local_Iterator = typename Compound::local_iterator;
49 using Const_Local_Iterator = typename Compound::const_local_iterator;
50 using Node_Type = typename Compound::node_type;
51 using Insert_Return_Type = typename Compound::insert_return_type;
52
54
55public:
56 //完美转发、初始化列表代理构造
57
62 template<typename... Args>
63 NBT_Compound(Args&&... args) : Compound(std::forward<Args>(args)...)
64 {}
65
69 NBT_Compound(std::initializer_list<typename Compound::value_type> init) : Compound(init)
70 {}
71
73 NBT_Compound(void) = default;
75 ~NBT_Compound(void) = default;
76
79 NBT_Compound(NBT_Compound &&_Move) noexcept :Compound(std::move(_Move))
80 {}
81
84 NBT_Compound(const NBT_Compound &_Copy) :Compound(_Copy)
85 {}
86
91 {
92 Compound::operator=(std::move(_Move));
93 return *this;
94 }
95
100 {
101 Compound::operator=(_Copy);
102 return *this;
103 }
104
107 const Compound &GetData(void) const noexcept
108 {
109 return *this;
110 }
111
116 bool operator==(const NBT_Compound &_Right) const noexcept
117 {
118 return (const Compound &)*this == (const Compound &)_Right;
119 }
120
125 bool operator!=(const NBT_Compound &_Right) const noexcept
126 {
127 return (const Compound &)*this != (const Compound &)_Right;
128 }
129
140 std::partial_ordering operator<=>(const NBT_Compound &_Right) const noexcept
141 {
142 if (auto _cmpSize = Compound::size() <=> _Right.size(); _cmpSize != 0)
143 {
144 return _cmpSize;
145 }
146
147 //数量相等,比较数据的排序
148 const auto _lSort = this->KeySortIt();
149 const auto _rSort = _Right.KeySortIt();
150 typename Compound::size_type _Size = Compound::size();
151
152 for (typename Compound::size_type _i = 0; _i < _Size; ++_i)
153 {
154 const auto &_lIt = _lSort[_i];
155 const auto &_rIt = _rSort[_i];
156
157 //首先比较名称,如果不同则返回
158 if (auto _cmpKey = _lIt->first <=> _rIt->first; _cmpKey != 0)
159 {
160 return _cmpKey;
161 }
162
163 //然后比较值,如果不同则返回
164 if (auto _cmpVal = _lIt->second <=> _rIt->second; _cmpVal != 0)
165 {
166 return _cmpVal;
167 }
168 }
169
170 //前面都没有返回,那么所有元素都相等
171 return std::partial_ordering::equivalent;
172 }
173
181 template<bool bAscending = true>
182 std::vector<typename Compound::iterator> KeySortIt(void)
183 {
184 std::vector<typename Compound::iterator> listSortIt;
185 listSortIt.reserve(Compound::size());
186 for (auto it = Compound::begin(); it != Compound::end(); ++it)
187 {
188 listSortIt.push_back(it);
189 }
190
191 std::sort(listSortIt.begin(), listSortIt.end(),
192 [](const auto &l, const auto &r) -> bool
193 {
194 if constexpr (bAscending)
195 {
196 return l->first < r->first;
197 }
198 else
199 {
200 return l->first > r->first;
201 }
202 }
203 );
204
205 return listSortIt;
206 }
207
215 template<bool bAscending = true>
216 std::vector<typename Compound::const_iterator> KeySortIt(void) const
217 {
218 std::vector<typename Compound::const_iterator> listSortIt;
219 listSortIt.reserve(Compound::size());
220 for (auto it = Compound::cbegin(); it != Compound::cend(); ++it)
221 {
222 listSortIt.push_back(it);
223 }
224
225 std::sort(listSortIt.begin(), listSortIt.end(),
226 [](const auto &l, const auto &r) -> bool
227 {
228 if constexpr (bAscending)
229 {
230 return l->first < r->first;
231 }
232 else
233 {
234 return l->first > r->first;
235 }
236 }
237 );
238
239 return listSortIt;
240 }
241
245
246 using Compound::begin;
247 using Compound::end;
248 using Compound::cbegin;
249 using Compound::cend;
250 using Compound::operator[];
251
253
254 //简化map查询
255
260 typename Compound::mapped_type &Get(const typename Compound::key_type &sTagName)
261 {
262 return Compound::at(sTagName);
263 }
264
269 const typename Compound::mapped_type &Get(const typename Compound::key_type &sTagName) const
270 {
271 return Compound::at(sTagName);
272 }
273
274
279 typename Compound::mapped_type *Has(const typename Compound::key_type &sTagName) noexcept
280 {
281 auto find = Compound::find(sTagName);
282 return find == Compound::end()
283 ? NULL
284 : &(find->second);
285 }
286
291 const typename Compound::mapped_type *Has(const typename Compound::key_type &sTagName) const noexcept
292 {
293 auto find = Compound::find(sTagName);
294 return find == Compound::end()
295 ? NULL
296 : &(find->second);
297 }
298
299 //简化map插入
300 //使用完美转发,不丢失引用、右值信息
301
310 template <typename K, typename V>
311 requires std::constructible_from<typename Compound::key_type, K &&> &&std::constructible_from<typename Compound::mapped_type, V &&>
312 std::pair<typename Compound::iterator, bool> Put(K &&sTagName, V &&vTagVal)
313 {
314 return Compound::insert_or_assign(std::forward<K>(sTagName), std::forward<V>(vTagVal));
315 }
316
325 template <typename K, typename V>
326 requires std::constructible_from<typename Compound::key_type, K &&> &&std::constructible_from<typename Compound::mapped_type, V &&>
327 std::pair<typename Compound::iterator, bool> TryPut(K &&sTagName, V &&vTagVal)
328 {
329 return Compound::try_emplace(std::forward<K>(sTagName), std::forward<V>(vTagVal));
330 }
331
335 bool Remove(const typename Compound::key_type &sTagName)
336 {
337 return Compound::erase(sTagName) != 0;//返回1即为成功,否则为0,标准库:返回值为删除的元素数(0 或 1)。
338 }
339
342 void Clear(void)
343 {
344 Compound::clear();
345 }
346
349 bool Empty(void) const noexcept
350 {
351 return Compound::empty();
352 }
353
356 typename Compound::size_type Size(void) const noexcept
357 {
358 return Compound::size();
359 }
360
365 void Merge(const NBT_Compound &_Copy)
366 {
367 Compound::merge(_Copy);
368 }
369
374 void Merge(NBT_Compound &&_Move)
375 {
376 Compound::merge(std::move(_Move));
377 }
378
382 bool Contains(const typename Compound::key_type &sTagName) const noexcept
383 {
384 return Compound::contains(sTagName);
385 }
386
392 template<typename Predicate>
393 bool ContainsIf(Predicate pred) const noexcept
394 {
395 return std::find_if(Compound::begin(), Compound::end(), pred) != Compound::end();
396 }
397
398
399//针对每种类型生成一个方便的函数
400//通过宏定义批量生成
401
405#define TYPE_GET_FUNC(type)\
406\
412bool Contains##type(const typename Compound::key_type &sTagName) const\
413{\
414 auto *p = Has(sTagName);\
415 return p != NULL && p->GetTag() == NBT_TAG::type;\
416}\
417\
418\
425const typename NBT_Type::type &Get##type(const typename Compound::key_type & sTagName) const\
426{\
427 return Compound::at(sTagName).Get##type();\
428}\
429\
430\
437typename NBT_Type::type &Get##type(const typename Compound::key_type & sTagName)\
438{\
439 return Compound::at(sTagName).Get##type();\
440}\
441\
442\
448const typename NBT_Type::type *Has##type(const typename Compound::key_type & sTagName) const noexcept\
450 auto *p = Has(sTagName);\
451 return p != NULL && p->Is##type()\
452 ? &(p->Get##type())\
453 : NULL;\
462typename NBT_Type::type *Has##type(const typename Compound::key_type & sTagName) noexcept\
463{\
464 auto *p = Has(sTagName);\
465 return p != NULL && p->Is##type()\
466 ? &(p->Get##type())\
467 : NULL;\
468}
469
470 /// @name 针对每种类型提供一个方便使用的函数,由宏批量生成
471 /// @brief 具体作用说明:
472 /// - Get开头+类型名的函数:直接获取指定标签名且对应类型的引用,异常由std::unordered_map的at与std::get具体实现决定
473 /// - Has开头 + 类型名的函数:判断指定标签名是否存在,且标签名对应的类型是否是指定类型,都符合则返回对应指针,否则返回NULL指针
474 /// @{
475
486 TYPE_GET_FUNC(String);
487 TYPE_GET_FUNC(List);
488 TYPE_GET_FUNC(Compound);
489
491
492#undef TYPE_GET_FUNC
493
497#define TYPE_PUT_FUNC(type)\
498
502\
507template <typename K>\
508requires std::constructible_from<typename Compound::key_type, K &&>\
509std::pair<typename Compound::iterator, bool> Put##type(K &&sTagName, const typename NBT_Type::type &vTagVal)\
511 return Put(std::forward<K>(sTagName), vTagVal);\
523template <typename K>\
524requires std::constructible_from<typename Compound::key_type, K &&>\
525std::pair<typename Compound::iterator, bool> Put##type(K &&sTagName, typename NBT_Type::type &&vTagVal)\
526{\
527 return Put(std::forward<K>(sTagName), std::move(vTagVal));\
528}\
529\
530\
539template <typename K>\
540requires std::constructible_from<typename Compound::key_type, K &&>\
541std::pair<typename Compound::iterator, bool> TryPut##type(K &&sTagName, const typename NBT_Type::type &vTagVal)\
542{\
543 return TryPut(std::forward<K>(sTagName), vTagVal);\
544}\
545\
546\
555template <typename K>\
556requires std::constructible_from<typename Compound::key_type, K &&>\
557std::pair<typename Compound::iterator, bool> TryPut##type(K &&sTagName, typename NBT_Type::type &&vTagVal)\
558{\
559 return TryPut(std::forward<K>(sTagName), std::move(vTagVal));\
560}
561
566
577 TYPE_PUT_FUNC(String);
578 TYPE_PUT_FUNC(List);
579 TYPE_PUT_FUNC(Compound);
580
582
583#undef TYPE_PUT_FUNC
584};
#define TYPE_PUT_FUNC(type)
不同类型名接口生成宏
定义 NBT_Compound.hpp:470
#define TYPE_GET_FUNC(type)
不同类型名接口生成宏
定义 NBT_Compound.hpp:405
@ 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:69
typename Compound::const_pointer Const_Pointer
标准库容器公开类型映射
定义 NBT_Compound.hpp:43
std::partial_ordering operator<=>(const NBT_Compound &_Right) const noexcept
三路比较运算符
定义 NBT_Compound.hpp:140
void Clear(void)
清空所有标签
定义 NBT_Compound.hpp:342
bool operator!=(const NBT_Compound &_Right) const noexcept
不等比较运算符
定义 NBT_Compound.hpp:125
typename Compound::mapped_type Mapped_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:36
NBT_Compound(void)=default
默认构造函数
std::vector< typename Compound::iterator > KeySortIt(void)
获取按键名排序的迭代器向量(非常量版本)
定义 NBT_Compound.hpp:182
NBT_Compound(NBT_Compound &&_Move) noexcept
移动构造函数
定义 NBT_Compound.hpp:79
NBT_Compound & operator=(const NBT_Compound &_Copy)
拷贝赋值运算符
定义 NBT_Compound.hpp:99
NBT_Compound & operator=(NBT_Compound &&_Move) noexcept
移动赋值运算符
定义 NBT_Compound.hpp:90
std::vector< typename Compound::const_iterator > KeySortIt(void) const
获取按键名排序的常量迭代器向量(常量版本)
定义 NBT_Compound.hpp:216
typename Compound::allocator_type Allocator_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:39
typename Compound::key_equal Key_Equal
标准库容器公开类型映射
定义 NBT_Compound.hpp:37
Compound::mapped_type & Get(const typename Compound::key_type &sTagName)
根据标签名获取对应的NBT值
定义 NBT_Compound.hpp:260
typename Compound::const_local_iterator Const_Local_Iterator
标准库容器公开类型映射
定义 NBT_Compound.hpp:49
void Merge(NBT_Compound &&_Move)
合并另一个NBT_Compound的内容(移动)
定义 NBT_Compound.hpp:374
typename Compound::value_type Value_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:38
const Compound & GetData(void) const noexcept
获取底层容器数据的常量引用
定义 NBT_Compound.hpp:107
const Compound::mapped_type * Has(const typename Compound::key_type &sTagName) const noexcept
搜索标签是否存在(常量版本)
定义 NBT_Compound.hpp:291
const Compound::mapped_type & Get(const typename Compound::key_type &sTagName) const
根据标签名获取对应的NBT值(常量版本)
定义 NBT_Compound.hpp:269
typename Compound::size_type Size_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:40
typename Compound::iterator Iterator
标准库容器公开类型映射
定义 NBT_Compound.hpp:46
typename Compound::const_reference Const_Reference
标准库容器公开类型映射
定义 NBT_Compound.hpp:45
bool Empty(void) const noexcept
检查容器是否为空
定义 NBT_Compound.hpp:349
bool Contains(const typename Compound::key_type &sTagName) const noexcept
检查是否包含指定标签
定义 NBT_Compound.hpp:382
NBT_Compound(const NBT_Compound &_Copy)
拷贝构造函数
定义 NBT_Compound.hpp:84
typename Compound::insert_return_type Insert_Return_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:51
typename Compound::key_type Key_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:35
typename Compound::const_iterator Const_Iterator
标准库容器公开类型映射
定义 NBT_Compound.hpp:47
typename Compound::hasher Hasher
标准库容器公开类型映射
定义 NBT_Compound.hpp:34
typename Compound::local_iterator Local_Iterator
标准库容器公开类型映射
定义 NBT_Compound.hpp:48
bool operator==(const NBT_Compound &_Right) const noexcept
相等比较运算符
定义 NBT_Compound.hpp:116
NBT_Compound(Args &&... args)
完美转发构造函数
定义 NBT_Compound.hpp:63
~NBT_Compound(void)=default
默认析构函数
Compound::mapped_type * Has(const typename Compound::key_type &sTagName) noexcept
搜索标签是否存在
定义 NBT_Compound.hpp:279
bool ContainsIf(Predicate pred) const noexcept
使用谓词检查是否存在满足条件的元素
定义 NBT_Compound.hpp:393
typename Compound::difference_type Difference_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:41
Compound::size_type Size(void) const noexcept
获取容器中元素的数量
定义 NBT_Compound.hpp:356
typename Compound::reference Reference
标准库容器公开类型映射
定义 NBT_Compound.hpp:44
void Merge(const NBT_Compound &_Copy)
合并另一个NBT_Compound的内容(拷贝)
定义 NBT_Compound.hpp:365
std::pair< typename Compound::iterator, bool > TryPut(K &&sTagName, V &&vTagVal)
原位构造键值对
定义 NBT_Compound.hpp:327
typename Compound::pointer Pointer
标准库容器公开类型映射
定义 NBT_Compound.hpp:42
std::pair< typename Compound::iterator, bool > Put(K &&sTagName, V &&vTagVal)
插入或替换键值对
定义 NBT_Compound.hpp:312
bool Remove(const typename Compound::key_type &sTagName)
删除指定标签
定义 NBT_Compound.hpp:335
typename Compound::node_type Node_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:50
用于格式化打印、序列化、计算哈希等功能
定义 NBT_Helper.hpp:25
这个类用于提供从NBT二进制流读取到NBT_Type::Compound对象的反序列化功能
定义 NBT_Reader.hpp:23
这个类用于提供从NBT_Type::Compound对象写出到NBT二进制流的序列化功能
定义 NBT_Writer.hpp:23
在std命名空间中添加类的默认hash特化以便unordered_map等容器自动获取
定义 NBT_String.hpp:422