1 #ifndef SERIALIZE_CORE_HH
2 #define SERIALIZE_CORE_HH
25 template<>
struct is_primitive<unsigned short> : std::true_type {};
32 template<>
struct is_primitive<unsigned long long> : std::true_type {};
41 template<
typename Archive,
typename T>
46 t.serialize(ar, version);
49 template<
typename Archive,
typename T1,
typename T2>
50 void serialize(Archive& ar, std::pair<T1, T2>& p,
unsigned )
52 ar.serialize(
"first", p.first,
57 static constexpr
unsigned value = 0;
109 for (
auto& i : info) {
110 if (i.e ==
t)
return i.str;
113 return "internal-error-unknown-enum-value";
116 for (
auto& i : info) {
117 if (i.str == str)
return i.e;
123 std::initializer_list<enum_string<T>> info;
126 #define SERIALIZE_ENUM(TYPE,INFO) \
127 template<> struct serialize_as_enum< TYPE > : serialize_as_enum_impl< TYPE > { \
128 serialize_as_enum() : serialize_as_enum_impl<TYPE>(INFO) {} \
163 "can't serialize ptr to primitive type");
170 template<
typename Archive>
178 static inline T*
getPointer(
const std::unique_ptr<T>&
t) {
return t.get(); }
179 template<
typename Archive>
180 static inline void setPointer(std::unique_ptr<T>&
t, T* p, Archive& ) {
188 template<
typename Archive>
189 static void setPointer(std::shared_ptr<T>&
t, T* p, Archive& ar) {
190 ar.resetSharedPtr(
t, p);
243 static const T*
begin(
const T (&array)[
N]) {
return &array[0]; }
244 static const T*
end (
const T (&array)[
N]) {
return &array[
N]; }
246 static constexpr
bool loadInPlace =
true;
248 static T*
output(T (&array)[
N]) {
return &array[0]; }
294 template<
typename Archive>
void operator()(Archive& ar,
const T&
t,
303 template<
typename Archive>
void operator()(Archive& ar,
const T&
t,
306 if (ar.translateEnumToString()) {
308 std::string str = sae.toString(
t);
318 Archive& ar,
const T&
t,
bool saveId,
319 const char* type =
nullptr,
bool saveConstrArgs =
false)
334 unsigned id = ar.generateId(&
t);
335 ar.attribute(
"id",
id);
339 ar.attribute(
"type", type);
343 if ((version != 0) && ar.needVersion()) {
344 if (!ar.canHaveOptionalAttributes() ||
346 ar.attribute(
"version", version);
350 if (saveConstrArgs) {
353 constrArgs.
save(ar,
t);
356 using TNC = std::remove_const_t<T>;
357 auto& t2 =
const_cast<TNC&
>(
t);
364 template<
typename Archive>
void operator()(Archive& ar,
const TP& tp2,
368 "must be serialized as pointer");
373 ar.attribute(
"id_ref",
id);
376 if (
unsigned id = ar.getId(tp)) {
377 ar.attribute(
"id_ref",
id);
379 if constexpr (std::is_polymorphic_v<T>) {
385 saver(ar, *tp,
true,
nullptr,
true);
392 template<
typename Archive>
void operator()(Archive& ar,
const TP& tp2)
395 "must be serialized as pointer");
404 ar.attribute(
"id_ref",
id);
409 template<
typename Archive>
void operator()(Archive& ar,
const TC& tc,
413 static_assert(sac::value,
"must be serialized as collection");
416 if ((
sac::size < 0) && (!ar.canCountChildren())) {
422 ar.serialize(
"size", n);
426 ar.serializeWithID(
"item", *
begin);
428 ar.serialize(
"item", *
begin);
437 : std::conditional_t<is_primitive<T>::value, PrimitiveSaver<T>,
438 std::conditional_t<serialize_as_enum<T>::value, EnumSaver<T>,
439 std::conditional_t<serialize_as_pointer<T>::value, PointerSaver<T>,
440 std::conditional_t<serialize_as_collection<T>::value, CollectionSaver<T>,
441 ClassSaver<T>>>>> {};
463 template<
typename Archive,
typename TUPLE>
466 static_assert(std::tuple_size_v<TUPLE> == 0,
467 "can't have constructor arguments");
473 template<
typename Archive,
typename TUPLE>
476 static_assert(std::tuple_size_v<TUPLE> == 0,
477 "can't have constructor arguments");
478 if (ar.translateEnumToString()) {
482 t = sae.fromString(str);
492 unsigned latestVersion);
494 unsigned latestVersion);
495 template<
typename T,
typename Archive>
unsigned loadVersion(Archive& ar)
498 if ((latestVersion != 0) && ar.needVersion()) {
501 return latestVersion;
506 template<
typename Archive,
typename TUPLE>
510 static_assert(std::tuple_size_v<TUPLE> == 0,
511 "can't have constructor arguments");
518 ar.attribute(
"id",
id);
520 ar.addPointer(
id, &
t);
526 version = loadVersion<T>(ar);
529 using TNC = std::remove_const_t<T>;
530 auto& t2 =
const_cast<TNC&
>(
t);
536 template<
typename Archive,
typename GlobalTuple>
537 T*
operator()(Archive& ar,
unsigned id, GlobalTuple globalArgs)
539 int version = loadVersion<T>(ar);
542 using TNC = std::remove_const_t<T>;
544 ConstrArgs constrArgs;
545 auto localArgs = constrArgs.
load(ar, version);
548 auto args = std::tuple_cat(globalArgs, localArgs);
552 auto tp = creator(args);
554 loader(ar, *tp, std::tuple<>(),
id, version);
560 template<
typename Archive,
typename TUPLE>
564 static_assert(std::is_same_v<TUPLE, ArgsType>,
565 "constructor arguments types must match");
566 return static_cast<T*
>(
574 : std::conditional_t<std::is_polymorphic_v<T>,
575 PolymorphicPointerLoader<T>,
576 NonPolymorphicPointerLoader<T>> {};
580 template<
typename Archive,
typename GlobalTuple>
581 void operator()(Archive& ar, TP& tp2, GlobalTuple globalArgs,
int )
584 "must be serialized as a pointer");
588 if (ar.canHaveOptionalAttributes() &&
589 ar.findAttribute(
"id_ref",
id)) {
592 ar.attribute(
"id",
id);
600 if (
void* p = ar.getPointer(
id)) {
601 tp =
static_cast<T*
>(p);
604 tp = loader(ar,
id, globalArgs);
613 template<
typename Archive>
617 "must be serialized as a pointer");
619 ar.attribute(
"id_ref",
id);
626 void* p = ar.getPointer(
id);
630 tp =
static_cast<T*
>(p);
640 template<
typename Archive,
typename TUPLE,
typename OUT_ITER>
641 void operator()(Archive& ar, TUPLE args, OUT_ITER it,
int id)
643 ar.doSerialize(
"item", *it, args,
id);
652 template<
typename Archive,
typename TUPLE,
typename OUT_ITER>
653 void operator()(Archive& ar, TUPLE args, OUT_ITER it,
int id)
655 typename sac::value_type elem;
656 ar.doSerialize(
"item", elem, args,
id);
657 *it = std::move(elem);
662 template<
typename Archive,
typename TUPLE>
665 assert(
id ==
one_of(0, -1));
667 static_assert(sac::value,
"must be serialized as a collection");
671 if (ar.canCountChildren()) {
672 n = ar.countChildren();
674 ar.serialize(
"size", n);
678 auto it = sac::output(tc);
681 loadOneElement(ar, args, it,
id);
687 : std::conditional_t<is_primitive<T>::value, PrimitiveLoader<T>,
688 std::conditional_t<serialize_as_enum<T>::value, EnumLoader<T>,
689 std::conditional_t<serialize_as_pointer<T>::value, PointerLoader<T>,
690 std::conditional_t<serialize_as_collection<T>::value, CollectionLoader<T>,
691 ClassLoader<T>>>>> {};
static void * load(Archive &ar, unsigned id, const void *args)
static void save(Archive &ar, T *t)
This file implemented 3 utility functions:
void enumError(const std::string &str)
unsigned loadVersion(Archive &ar)
void serialize(Archive &ar, T &t, unsigned version)
void pointerError(unsigned id)
unsigned loadVersionHelper(MemInputArchive &, const char *, unsigned)
size_t size(std::string_view utf8)
auto distance(octet_iterator first, octet_iterator last)
void operator()(Archive &ar, T &t, TUPLE, int id=0, int version=-1)
void operator()(Archive &ar, const T &t, bool saveId, const char *type=nullptr, bool saveConstrArgs=false)
void operator()(Archive &ar, TUPLE args, OUT_ITER it, int id)
void operator()(Archive &ar, TUPLE args, OUT_ITER it, int id)
void operator()(Archive &ar, TC &tc, TUPLE args, int id=0)
void operator()(Archive &ar, const TC &tc, bool saveId)
Utility to do T* t = new T(...)
void operator()(Archive &ar, T &t, TUPLE, int)
void operator()(Archive &ar, const T &t, bool)
void operator()(Archive &ar, TP &tp2)
void operator()(Archive &ar, const TP &tp2)
T * operator()(Archive &ar, unsigned id, GlobalTuple globalArgs)
void operator()(Archive &ar, TP &tp2, GlobalTuple globalArgs, int)
void operator()(Archive &ar, const TP &tp2, bool)
Store association between polymorphic class (base- or subclass) and the list of constructor arguments...
T * operator()(Archive &ar, unsigned id, TUPLE args)
void operator()(Archive &ar, T &t, TUPLE, int)
void operator()(Archive &ar, const T &t, bool)
Store serialization-version number of a class.
static constexpr unsigned value
Serialize (local) constructor arguments.
type load(Archive &, unsigned)
void save(Archive &, const T &)
static const T * begin(const T(&array)[N])
static T * output(T(&array)[N])
static void prepare(T(&)[N], int)
static const T * end(const T(&array)[N])
std::string toString(T t) const
T fromString(const std::string &str) const
serialize_as_enum_impl(std::initializer_list< enum_string< T >> info_)
static void setPointer(T *&t, T *p, Archive &)
static T * getPointer(T *t)
static T * getPointer(const std::shared_ptr< T > &t)
static void setPointer(std::shared_ptr< T > &t, T *p, Archive &ar)
static T * getPointer(const std::unique_ptr< T > &t)
static void setPointer(std::unique_ptr< T > &t, T *p, Archive &)
constexpr void repeat(T n, Op op)
Repeat the given operation 'op' 'n' times.
constexpr auto begin(const zstring_view &x)
constexpr auto end(const zstring_view &x)