Jyaif
7 days ago
Your lib requires manually creating both a serializing and deserializing function. If the functions are out of sync, bad things happen.
Consider copying Cereal, which solves this problem by requiring you to create a single templated function ( https://uscilab.github.io/cereal/ )
Chaosvex
7 days ago
Thanks, that is definitely a downside to the shift operator overloading approach. I'll take that onboard and investigate whether a single operator to handle both would mesh with the current design.
jcelerier
7 days ago
You can just use the boost.pfr technique to iterate fields though. Or if you want, starting from C++26 and e.g. clang-21: https://gcc.godbolt.org/z/G1TqP3a8P
#include <print>
#include <type_traits>
namespace hexi {
struct streamer { };
template<typename T>
void operator<<(streamer& s, const T& e) {
if constexpr(std::is_integral_v<T>) {
std::println("number: {}", e);
} else if constexpr(std::is_aggregate_v<T>) {
auto& [...mems] = e;
(std::println("member: {}", mems), ...);
}
}
}
struct user_type {
int x;
std::string y;
};
int main() {
hexi::streamer s;
s << 123;
s << user_type{.x = 456, .y = "foo"};
}
or with boost.pfr as a polyfill until then, which allows to do this back to C++14lionkor
7 days ago
like boost serialize, which overloads the & operator
Chaosvex
3 days ago
Thanks again for this comment. Consider Cereal copied, now only a single function is required.