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
270 typename Compound::mapped_type &Get(const typename Compound::key_type &sTagName)
271 {
272 return Compound::at(sTagName);
273 }
274
279 const typename Compound::mapped_type &Get(const typename Compound::key_type &sTagName) const
280 {
281 return Compound::at(sTagName);
282 }
283
284
289 typename Compound::mapped_type *Has(const typename Compound::key_type &sTagName) noexcept
290 {
291 auto find = Compound::find(sTagName);
292 return find == Compound::end()
293 ? nullptr
294 : &(find->second);
295 }
296
301 const typename Compound::mapped_type *Has(const typename Compound::key_type &sTagName) const noexcept
302 {
303 auto find = Compound::find(sTagName);
304 return find == Compound::end()
305 ? nullptr
306 : &(find->second);
307 }
308
309 //简化map插入
310 //使用完美转发,不丢失引用、右值信息
311
320 template <typename K, typename V>
321 requires std::constructible_from<typename Compound::key_type, K &&> &&std::constructible_from<typename Compound::mapped_type, V &&>
322 std::pair<typename Compound::iterator, bool> Put(K &&sTagName, V &&vTagVal)
323 {
324 return Compound::insert_or_assign(std::forward<K>(sTagName), std::forward<V>(vTagVal));
325 }
326
335 template <typename K, typename V>
336 requires std::constructible_from<typename Compound::key_type, K &&> &&std::constructible_from<typename Compound::mapped_type, V &&>
337 std::pair<typename Compound::iterator, bool> TryPut(K &&sTagName, V &&vTagVal)
338 {
339 return Compound::try_emplace(std::forward<K>(sTagName), std::forward<V>(vTagVal));
340 }
341
345 bool Remove(const typename Compound::key_type &sTagName)
346 {
347 return Compound::erase(sTagName) != 0;//返回1即为成功,否则为0,标准库:返回值为删除的元素数(0 或 1)。
348 }
349
352 void Clear(void)
353 {
354 Compound::clear();
355 }
356
359 bool Empty(void) const noexcept
360 {
361 return Compound::empty();
362 }
363
366 typename Compound::size_type Size(void) const noexcept
367 {
368 return Compound::size();
369 }
370
375 void Merge(const NBT_Compound &_Copy)
376 {
377 Compound::merge(_Copy);
378 }
379
384 void Merge(NBT_Compound &&_Move)
385 {
386 Compound::merge(std::move(_Move));
387 }
388
392 bool Contains(const typename Compound::key_type &sTagName) const noexcept
393 {
394 return Compound::contains(sTagName);
395 }
396
402 template<typename Predicate>
403 bool ContainsIf(Predicate pred) const noexcept
404 {
405 return std::find_if(Compound::begin(), Compound::end(), pred) != Compound::end();
406 }
407
408
409//针对每种类型生成一个方便的函数
410//通过宏定义批量生成
411
415#define TYPE_GET_FUNC(type)\
416\
422bool Contains##type(const typename Compound::key_type &sTagName) const\
423{\
424 auto *p = Has(sTagName);\
425 return p != nullptr && p->Is##type();\
426}\
427\
428\
435const typename NBT_Type::type &Get##type(const typename Compound::key_type & sTagName) const\
436{\
437 return Compound::at(sTagName).Get##type();\
438}\
439\
440\
447typename NBT_Type::type &Get##type(const typename Compound::key_type & sTagName)\
448{\
449 return Compound::at(sTagName).Get##type();\
450}\
451\
452\
458const typename NBT_Type::type *Has##type(const typename Compound::key_type & sTagName) const noexcept\
460 auto *p = Has(sTagName);\
461 return p != nullptr\
462 ? p->GetIf##type()\
463 : nullptr;\
472typename NBT_Type::type *Has##type(const typename Compound::key_type & sTagName) noexcept\
473{\
474 auto *p = Has(sTagName);\
475 return p != nullptr\
476 ? p->GetIf##type()\
477 : nullptr;\
478}
479
480 /// @name 针对每种类型提供一个方便使用的函数,由宏批量生成
481 /// @brief 具体作用说明:
482 /// - Get开头+类型名的函数:直接获取指定标签名且对应类型的引用,异常由std::unordered_map的at与std::get具体实现决定
483 /// - Has开头 + 类型名的函数:判断指定标签名是否存在,且标签名对应的类型是否是指定类型,都符合则返回对应指针,否则返回nullptr指针
484 /// @{
485
496 TYPE_GET_FUNC(String);
497 TYPE_GET_FUNC(List);
498 TYPE_GET_FUNC(Compound);
499
501
502#undef TYPE_GET_FUNC
503
507#define TYPE_PUT_FUNC(type)\
508
512\
517template <typename K>\
518requires std::constructible_from<typename Compound::key_type, K &&>\
519std::pair<typename Compound::iterator, bool> Put##type(K &&sTagName, const typename NBT_Type::type &vTagVal)\
521 return Put(std::forward<K>(sTagName), vTagVal);\
533template <typename K>\
534requires std::constructible_from<typename Compound::key_type, K &&>\
535std::pair<typename Compound::iterator, bool> Put##type(K &&sTagName, typename NBT_Type::type &&vTagVal)\
536{\
537 return Put(std::forward<K>(sTagName), std::move(vTagVal));\
538}\
539\
540\
549template <typename K>\
550requires std::constructible_from<typename Compound::key_type, K &&>\
551std::pair<typename Compound::iterator, bool> TryPut##type(K &&sTagName, const typename NBT_Type::type &vTagVal)\
552{\
553 return TryPut(std::forward<K>(sTagName), vTagVal);\
554}\
555\
556\
565template <typename K>\
566requires std::constructible_from<typename Compound::key_type, K &&>\
567std::pair<typename Compound::iterator, bool> TryPut##type(K &&sTagName, typename NBT_Type::type &&vTagVal)\
568{\
569 return TryPut(std::forward<K>(sTagName), std::move(vTagVal));\
570}
571
576
587 TYPE_PUT_FUNC(String);
588 TYPE_PUT_FUNC(List);
589 TYPE_PUT_FUNC(Compound);
590
592
593#undef TYPE_PUT_FUNC
594};
#define TYPE_PUT_FUNC(type)
不同类型名接口生成宏
定义 NBT_Compound.hpp:480
#define TYPE_GET_FUNC(type)
不同类型名接口生成宏
定义 NBT_Compound.hpp:415
@ 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:352
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
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
Compound::mapped_type & Get(const typename Compound::key_type &sTagName)
根据标签名获取对应的NBT值
定义 NBT_Compound.hpp:270
typename Compound::const_local_iterator Const_Local_Iterator
标准库容器公开类型映射
定义 NBT_Compound.hpp:52
void Merge(NBT_Compound &&_Move)
合并另一个NBT_Compound的内容(移动)
定义 NBT_Compound.hpp:384
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 typename Compound::key_type &sTagName) const noexcept
搜索标签是否存在(常量版本)
定义 NBT_Compound.hpp:301
const Compound::mapped_type & Get(const typename Compound::key_type &sTagName) const
根据标签名获取对应的NBT值(常量版本)
定义 NBT_Compound.hpp:279
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:359
bool Contains(const typename Compound::key_type &sTagName) const noexcept
检查是否包含指定标签
定义 NBT_Compound.hpp:392
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
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
默认析构函数
Compound::mapped_type * Has(const typename Compound::key_type &sTagName) noexcept
搜索标签是否存在
定义 NBT_Compound.hpp:289
bool ContainsIf(Predicate pred) const noexcept
使用谓词检查是否存在满足条件的元素
定义 NBT_Compound.hpp:403
typename Compound::difference_type Difference_Type
标准库容器公开类型映射
定义 NBT_Compound.hpp:44
Compound::size_type Size(void) const noexcept
获取容器中元素的数量
定义 NBT_Compound.hpp:366
typename Compound::reference Reference
标准库容器公开类型映射
定义 NBT_Compound.hpp:47
void Merge(const NBT_Compound &_Copy)
合并另一个NBT_Compound的内容(拷贝)
定义 NBT_Compound.hpp:375
std::pair< typename Compound::iterator, bool > TryPut(K &&sTagName, V &&vTagVal)
原位构造键值对
定义 NBT_Compound.hpp:337
typename Compound::pointer Pointer
标准库容器公开类型映射
定义 NBT_Compound.hpp:45
std::pair< typename Compound::iterator, bool > Put(K &&sTagName, V &&vTagVal)
插入或替换键值对
定义 NBT_Compound.hpp:322
bool Remove(const typename Compound::key_type &sTagName)
删除指定标签
定义 NBT_Compound.hpp:345
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
在std命名空间中添加类的默认hash特化以便unordered_map等容器自动获取
定义 NBT_String.hpp:456