Created
July 7, 2016 19:34
-
-
Save aruslan/6f0be43982f22ba3aaa68e1181ff5d1a to your computer and use it in GitHub Desktop.
For tilarids: an example of a simple serialization with no changes to serializable structs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <sstream> | |
#include <string> | |
#include <vector> | |
#include <utility> | |
//------------ ORIGINAL CODE. | |
// a.h - NO CHANGES, verbatim | |
// should be serializable. -- MAY NEED TO ADD SOME [[*]] ATTRIBUTE. | |
class A { | |
public: | |
A(int x, int y): x_(x), y_(y) {} | |
virtual ~A() {} | |
private: | |
int x_; | |
int y_; | |
}; | |
// b.h - NO CHANGES, verbatim | |
// should be serializable. -- MAY NEED TO ADD SOME [[*]] ATTRIBUTE. | |
class B : public A { | |
public: | |
B(int x, int y, double z): A(x, y), z_(z) {} | |
virtual ~B() {} | |
private: | |
double z_; | |
}; | |
// c.h - NO CHANGES, verbatim | |
// should be serializable. -- MAY NEED TO ADD SOME [[*]] ATTRIBUTE. | |
class C { | |
public: | |
explicit C(int n) { | |
v_b_.reserve(n); | |
v_.reserve(n); | |
for (int i = 0; i < n; ++i) { | |
v_b_.emplace_back(i, i + 1, i * 42); | |
v_.push_back(i); | |
} | |
} | |
private: | |
std::vector<B> v_b_; | |
std::vector<int> v_; | |
}; | |
//------------ NEWLY ADDED CODE. | |
// is_serializable.h -- ONLY IN CASE SOMEONE WANTS TO STATIC_ASSERT THAT serialize(T) IS DECLARED. | |
template<typename T> | |
inline constexpr auto isSerializableImpl(int) -> decltype(serialize(std::declval<std::ostream&>(), std::declval<const T&>()), bool()) { return true; } | |
template<typename T> | |
inline constexpr auto isSerializableImpl(...) -> bool { return false; } | |
template<typename T> | |
inline constexpr auto isSerializable() -> bool { return isSerializableImpl<T>(0); } | |
//------------ USED ONLY BY THE AUTOGENERATED CODE. | |
// serializable_utilities.h -- VARIOUS UTILITIES USED BY AUTOGENERATED CODE. | |
inline void serialize(std::ostream& os, int v) { os << v << " "; } | |
inline void serialize(std::ostream& os, double v) { os << v << " "; } | |
inline void serialize(std::ostream& os, size_t v) { os << v << " "; } | |
template<typename T> | |
inline void serialize(std::ostream& os, const std::vector<T>& ts) { | |
serialize(os, ts.size()); | |
for(auto& t : ts) serialize(os, t); | |
} | |
template<typename T, typename T::type TM> | |
struct acquire_access { friend typename T::type access(T) { return TM; } }; | |
//------------ AUTOGENERATED CODE. | |
// serializables.h -- AUTOMATICALLY GENERATED | |
class A; | |
void serialize(std::ostream& os, const A& v); | |
class B; | |
void serialize(std::ostream& os, const B& v); | |
class C; | |
void serialize(std::ostream& os, const C& v); | |
//------------ AUTOGENERATED CODE. | |
// a_serialization.cc -- AUTOMATICALLY GENERATED | |
struct A_x_ { typedef int A::*type; friend type access(A_x_); }; | |
template struct acquire_access<A_x_, &A::x_>; | |
struct A_y_ { typedef int A::*type; friend type access(A_y_); }; | |
template struct acquire_access<A_y_, &A::y_>; | |
void serialize(std::ostream& os, const A& v) { | |
serialize(os, v.*access(A_x_())); | |
serialize(os, v.*access(A_y_())); | |
} | |
// b_serialization.cc -- AUTOMATICALLY GENERATED | |
struct B_z_ { typedef double B::*type; friend type access(B_z_); }; | |
template struct acquire_access<B_z_, &B::z_>; | |
void serialize(std::ostream& os, const B& v) { | |
serialize(os, static_cast<const A&>(v)); | |
serialize(os, v.*access(B_z_())); | |
} | |
// c_serialization.cc -- AUTOMATICALLY GENERATED | |
struct C_v_b_ { typedef std::vector<B> C::*type; friend type access(C_v_b_); }; | |
template struct acquire_access<C_v_b_, &C::v_b_>; | |
struct C_v_v_ { typedef std::vector<int> C::*type; friend type access(C_v_v_); }; | |
template struct acquire_access<C_v_v_, &C::v_>; | |
void serialize(std::ostream& os, const C& v) { | |
serialize(os, v.*access(C_v_b_())); | |
serialize(os, v.*access(C_v_v_())); | |
} | |
//------------ ORIGINAL CODE. | |
// main.cpp -- ALMOST VERBATIM, CHANGES ARE HIGHLIGHTED | |
// ADDED IF YOU WANT to assert that the types are serializable | |
static_assert(isSerializable<A>(), "A should be serializable"); | |
static_assert(isSerializable<B>(), "B should be serializable"); | |
static_assert(isSerializable<C>(), "C should be serializable"); | |
struct D {}; | |
static_assert(!isSerializable<D>(), "D should NOT be serializable"); | |
void serialize(const std::string& filename, const C& v) { | |
std::stringstream ss; | |
serialize(ss, v); | |
std::cout << filename << ": " << ss.str() << std::endl; | |
} | |
C deserialize(const std::string& filename) { | |
// todo | |
return C(0); | |
} | |
int main() { | |
C test1(3); | |
C test2(5); | |
serialize("test1.bin", test1); | |
serialize("test2.bin", test2); | |
C test1_new = deserialize("test1.bin"); | |
C test2_new = deserialize("test2.bin"); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment