Skip to content

Instantly share code, notes, and snippets.

@aruslan
Created July 7, 2016 19:34
Show Gist options
  • Save aruslan/6f0be43982f22ba3aaa68e1181ff5d1a to your computer and use it in GitHub Desktop.
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.
#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