16 #include <type_traits>
24 class LastDeltaBlocks;
29 template<
typename T1,
typename T2>
31 return 31 * std::hash<T1>()(p.first) +
32 std::hash<T2>()(p.second);
37 template<
typename T>
struct SerializeClassVersion;
87 template<
typename Base,
typename T>
110 template<
typename Base,
typename T>
236 void attribute(
const char* name,
const char* value);
342 inline Derived&
self()
344 return static_cast<Derived&
>(*this);
352 [[nodiscard]]
inline bool isLoader()
const {
return false; }
374 [[nodiscard]]
static NEVER_INLINE bool addressOnStack(
const void* p)
388 template<
typename T> [[nodiscard]]
unsigned generateId(
const T* p)
400 if constexpr (std::is_polymorphic_v<T>) {
401 return generateID1(p);
403 return generateID2(p,
typeid(T));
407 template<
typename T> [[nodiscard]]
unsigned getId(
const T* p)
409 if constexpr (std::is_polymorphic_v<T>) {
412 return getID2(p,
typeid(T));
420 [[nodiscard]]
unsigned generateID1(
const void* p);
421 [[nodiscard]]
unsigned generateID2(
const void* p,
const std::type_info& typeInfo);
422 [[nodiscard]]
unsigned getID1(
const void* p);
423 [[nodiscard]]
unsigned getID2(
const void* p,
const std::type_info& typeInfo);
431 template<
typename Derived>
435 template<
typename Base,
typename T>
441 "base and derived must have same version when "
442 "using serializeInlinedBase()");
450 template<
typename T,
typename... Args>
455 saver(this->
self(), t,
true);
461 void serialize_blob(
const char* tag,
const void* data,
size_t len,
464 template<
typename T>
void serialize(
const char* tag,
const T&
t)
468 saver(this->
self(), t,
false);
475 saver(this->
self(), t);
480 static_assert(std::is_polymorphic_v<T>,
481 "must be a polymorphic type");
495 this->
self().saveChar(c);
508 [[nodiscard]]
inline bool isLoader()
const {
return true; }
522 [[nodiscard]]
unsigned getId(
const void* p)
const;
530 auto it = sharedPtrMap.
find(r);
531 if (it ==
end(sharedPtrMap)) {
535 s = std::static_pointer_cast<T>(it->second);
547 template<
typename Derived>
551 template<
typename T,
typename... Args>
563 using TNC = std::remove_const_t<T>;
564 auto& tnc =
const_cast<TNC&
>(
t);
566 loader(this->
self(), tnc, std::tuple<>(), -1);
572 using TNC = std::remove_const_t<T>;
573 auto& tnc =
const_cast<TNC&
>(
t);
575 loader(this->
self(), tnc);
580 static_assert(std::is_polymorphic_v<T>,
581 "must be a polymorphic type");
595 this->
self().loadChar(c);
601 template<
typename T,
typename TUPLE>
605 using TNC = std::remove_const_t<T>;
606 auto& tnc =
const_cast<TNC&
>(
t);
608 loader(this->
self(), tnc, args,
id);
641 std::vector<std::shared_ptr<DeltaBlock>>& deltaBlocks_,
642 bool reverseSnapshot_)
643 : lastDeltaBlocks(lastDeltaBlocks_)
644 , deltaBlocks(deltaBlocks_)
645 , reverseSnapshot(reverseSnapshot_)
651 assert(openSections.empty());
657 template<
typename T>
void save(
const T&
t)
665 void save(
const std::string& s);
666 void serialize_blob(
const char* tag,
const void* data,
size_t len,
670 template<
typename T,
typename ...Args>
679 serialize_group(std::tuple<>(), tag,
t, std::forward<Args>(args)...);
681 template<
typename T,
size_t N>
685 buffer.
insert(&
t[0],
N *
sizeof(T));
693 openSections.push_back(beginPos);
697 assert(!openSections.empty());
699 size_t beginPos = openSections.back();
700 openSections.pop_back();
701 size_t skip = endPos - beginPos;
702 buffer.
insertAt(beginPos -
sizeof(skip),
703 &skip,
sizeof(skip));
709 void put(
const void* data,
size_t len)
720 template<
typename ...Args>
721 ALWAYS_INLINE void serialize_group(
const std::tuple<Args...>& tuple)
726 template<
typename TUPLE,
typename T,
typename ...Args>
727 ALWAYS_INLINE void serialize_group(
const TUPLE& tuple,
const char* tag,
const T&
t, Args&& ...args)
730 if constexpr (SerializeAsMemcpy<T>::value) {
733 serialize_group(std::tuple_cat(tuple, std::tuple(&
t)), std::forward<Args>(args)...);
736 serialize_group(tuple, std::forward<Args>(args)...);
742 std::vector<size_t> openSections;
743 LastDeltaBlocks& lastDeltaBlocks;
744 std::vector<std::shared_ptr<DeltaBlock>>& deltaBlocks;
745 const bool reverseSnapshot;
752 const std::vector<std::shared_ptr<DeltaBlock>>& deltaBlocks_)
754 , deltaBlocks(deltaBlocks_)
768 template<
typename T>
void load(T&
t)
776 void load(std::string& s);
777 [[nodiscard]] std::string_view
loadStr();
782 template<
typename T,
typename ...Args>
786 serialize_group(std::tuple<>(), tag,
t, std::forward<Args>(args)...);
789 template<
typename T,
size_t N>
793 buffer.
read(&
t[0],
N *
sizeof(T));
806 void get(
void* data,
size_t len)
809 buffer.
read(data, len);
814 template<
typename TUPLE>
817 auto read = [&](
auto* p) { buffer.
read(p,
sizeof(*p)); };
818 std::apply([&](
auto&&... args) { (read(args), ...); }, tuple);
820 template<
typename TUPLE,
typename T,
typename ...Args>
821 ALWAYS_INLINE void serialize_group(
const TUPLE& tuple,
const char* tag, T&
t, Args&& ...args)
823 if constexpr (SerializeAsMemcpy<T>::value) {
825 serialize_group(std::tuple_cat(tuple, std::tuple(&
t)), std::forward<Args>(args)...);
828 serialize_group(tuple, std::forward<Args>(args)...);
834 const std::vector<std::shared_ptr<DeltaBlock>>& deltaBlocks;
852 template<
typename T>
void save(
const T&
t)
857 void save(
const std::string& str);
859 void save(
unsigned char b);
860 void save(
signed char c);
863 void save(
unsigned u);
864 void save(
unsigned long long ull);
872 template<
typename T,
typename ...Args>
877 this->
self().
serialize(std::forward<Args>(args)...);
886 void endTag(
const char* tag);
892 template<
typename T>
void attribute(
const char* name,
const T&
t)
896 void attribute(
const char* name, std::string str);
898 void attribute(
const char* name,
unsigned u);
903 std::vector<XMLElement*> current;
911 [[nodiscard]]
inline bool versionAtLeast(
unsigned actual,
unsigned required)
const
913 return actual >= required;
915 [[nodiscard]]
inline bool versionBelow(
unsigned actual,
unsigned required)
const
917 return actual < required;
920 template<
typename T>
void load(T&
t)
924 std::istringstream is(str);
929 void load(
unsigned char& b);
930 void load(
signed char& c);
933 void load(
unsigned& u);
934 void load(
unsigned long long& ull);
935 void load(std::string&
t);
936 [[nodiscard]] std::string_view
loadStr();
943 template<
typename T,
typename ...Args>
948 this->
self().
serialize(std::forward<Args>(args)...);
957 void endTag(
const char* tag);
963 std::istringstream is(str);
970 void attribute(
const char* name, std::string&
t);
971 void attribute(
const char* name,
int& i);
972 void attribute(
const char* name,
unsigned& u);
980 std::vector<std::pair<const XMLElement*, size_t>> elems;
983 #define INSTANTIATE_SERIALIZE_METHODS(CLASS) \
984 template void CLASS::serialize(MemInputArchive&, unsigned); \
985 template void CLASS::serialize(MemOutputArchive&, unsigned); \
986 template void CLASS::serialize(XmlInputArchive&, unsigned); \
987 template void CLASS::serialize(XmlOutputArchive&, unsigned);
iterator emplace_noDuplicateCheck(Args &&... args)
iterator find(const K &key)
bool isReverseSnapshot() const
Is this a reverse-snapshot?
void beginTag(const char *)
Indicate begin of a tag.
bool translateEnumToString() const
Does this archive store enums as strings.
void endTag(const char *)
Indicate begin of a tag.
bool canCountChildren() const
Some archives (like XML archives) can count the number of subtags that belong to the current tag.
bool hasAttribute(const char *)
Check the presence of a (optional) attribute.
void attribute(const char *name, T &t)
Load/store an attribute from/in the archive.
int countChildren() const
Count the number of child tags.
bool findAttribute(const char *, unsigned &)
Optimization: combination of hasAttribute() and getAttribute().
void serializeInlinedBase(T &t, unsigned version)
Serialize the base class of this classtype.
void serializeBase(T &t)
Is this archive a loader or a saver.
bool canHaveOptionalAttributes() const
Some archives (like XML archives) can store optional attributes.
bool needVersion() const
Does this archive store version information.
MemOutputArchive(LastDeltaBlocks &lastDeltaBlocks_, std::vector< std::shared_ptr< DeltaBlock >> &deltaBlocks_, bool reverseSnapshot_)
ALWAYS_INLINE void serialize(const char *tag, const T &t, Args &&...args)
ALWAYS_INLINE void serialize(const char *, const T(&t)[N], std::enable_if_t< SerializeAsMemcpy< T >::value > *=nullptr)
MemBuffer< uint8_t > releaseBuffer(size_t &size)
void serialize_blob(const char *tag, const void *data, size_t len, bool diff=true)
bool isReverseSnapshot() const
unsigned generateId(const T *p)
unsigned getId(const T *p)
bool versionBelow(unsigned, unsigned) const
OutputArchiveBase2()=default
bool versionAtLeast(unsigned, unsigned) const
void serialize_blob(const char *tag, const void *data, size_t len, bool diff=true)
void serializePolymorphic(const char *tag, const T &t)
void serializePointerID(const char *tag, const T &t)
void serializeOnlyOnce(const char *tag, const T &t)
void serializeChar(const char *tag, char c)
OutputArchiveBase()=default
void serializeInlinedBase(T &t, unsigned version)
void serialize(const char *tag, const T &t)
void serializeWithID(const char *tag, const T &t, Args...)
void insertAt(size_t pos, const void *data, size_t len)
Insert data at a given position.
ALWAYS_INLINE void insert_tuple_ptr(const TUPLE &tuple)
Insert all the elements of the given tuple.
size_t getPosition() const
Get the current size of the buffer.
void insert(const void *data, size_t len)
Insert data at the end of this buffer.
static void init(const char *tag, Archive &ar, void *t)
static void save(Archive &ar, T *t)
void saveImpl(const T &t)
XmlOutputArchive(zstring_view filename)
ALWAYS_INLINE void serialize(const char *tag, const T &t, Args &&...args)
bool canHaveOptionalAttributes() const
void attributeImpl(const char *name, const T &t)
bool canCountChildren() const
bool translateEnumToString() const
void endTag(const char *tag)
void beginTag(const char *tag)
void attribute(const char *name, const T &t)
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
string getName(KeyCode keyCode)
Translate key code to key name.
This file implemented 3 utility functions:
constexpr const char *const filename
void serialize(Archive &ar, T &t, unsigned version)
size_t size(std::string_view utf8)
std::string strCat(Ts &&...ts)
size_t operator()(const std::pair< T1, T2 > &p) const
Store serialization-version number of a class.
constexpr auto end(const zstring_view &x)