-
Notifications
You must be signed in to change notification settings - Fork 235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
struct_pack support user-defined type which is not in struct_pack type system #472
Comments
首先,struct_pack是支持非侵入式支持第三方库的。但前提条件是该类型可以作为合法的struct_pack类型。 例如,对于boost::container::flat_map,以下代码是合法的: boost::container::flat_map m;
auto buffer = struct_pack::serialize(m);
auto result = struct_pack::deserialize<boost::container::flat_map>(buffer); |
其次,对于用户给定的结构体,如果只想序列化其中一部分字段,也可以做到非侵入式支持: struct hi {
int a;
double b;
};
STRUCT_PACK_REFL(hi,a);
hi h;
struct_pack::serialize(h); // only save a; |
NTL::ZZ 应该是一个大整数类型,不属于struct_pack的类型系统。因此,目前确实无法做到非侵入式支持。 我的想法是:对于struct_pack无法支持的类型,可以在类型系统中统一视作未知类型来处理。用户同样只需要自定义两个函数即可。 namespace NTL{
template<struct_pack::writer_t writer_t>
void serialize_to(writer_t writer, const ZZ&zz);
template<struct_pack::reader_t reader_t>
void deserialize_to(ZZ&zz, reader_t reader);
} 具体设计有待进一步讨论。 |
感谢回答, 不过我对 https://github.com/libntl/ntl/blob/main/include/NTL/ZZ.h 想了解下, 这里定义的ZZ类是通过什么判断属于非平凡结构体的? |
struct_pack不支持NTL::ZZ的原因倒不是因为他是非平凡结构体,而是因为结构体的成员含有裸指针类型。struct_pack不支持序列化裸指针,因为无法确定指针类型的语义到底是指向对象还是数组。 |
详细设计如下:对于每一个自定义类型,用户需要在相同namespace下定义三个函数:
#include <ylt/struct_pack.hpp>
namespace NTL{
std::size_t get_needed_size(NTL::ZZ& z) {
return sizeof(uint64_t)+NTL::BytesFromZZ(z);
};
template<struct_pack::writer_t writer_t>
void serialize_to(writer_t writer, const ZZ&z) {
std::vector<unsigned char> buf(NTL::NumBytes(z));
NTL::BytesFromZZ(buf.data(), z, static_cast<long>(buf.size()));
uint64_t sz=buf.size();
struct_pack::write(writer,sz);
struct_pack::write(writer,buf.data(),buf.size());
}
template<struct_pack::reader_t reader_t>
void deserialize_to(reader_t reader,ZZ&z) {
uint64_t sz;
struct_pack::read(reader,sz);
std::string_view buf;
if constexpr( requires{reader.read_view(std::size_t{});}) {
buf = reader.read_view(sz);
}
else {
std::vector<unsigned char> tmp;
buf.resize(sz);
struct_pack::read(reader,tmp.data(),tmp.size());
buf={tmp.data(),tmp.size()}
}
NTL::ZZFromBytes(z, buf.data(), static_cast<long>(buf.size()));
}
}
|
必须定义 |
算法限制,struct_pack的二进制格式+流式读写,导致必须先在序列化之前获取所需的长度。 |
emmm...这个要求似乎可以移除,不过需要对代码结构做一些调整,理论上可以将get_needed_size()作为一个可选项。 |
Search before asking
What happened + What you expected to happen
咨询问题, 请问 struct_pack 是否能够实现非侵入式序列化第三方库.
比如下面这个例子, 通过自定义两个模板函数load/save, 使用boost
serialazation模块实现对第三方库
libntl
中的比较复杂类型NTL::ZZ
的序列化, 而不用对这个库本身进行修改, 因此修改是非侵入式的.我想知道在
struct_pack
中应该怎么在不更改第三方库的前提下实现这样的需求? 或者有什么其他的解决方案Reproduction way
Anything else
示例中的库以及头文件地址
https://github.com/libntl/ntl
https://github.com/libntl/ntl/blob/main/include/NTL/ZZ.h
Are you willing to submit a PR?
The text was updated successfully, but these errors were encountered: