zeus

Unnamed repository; edit this file 'description' to name the repository.
git clone Unknown
Log | Files | Refs

factory_serialization.cpp (2758B)


0 #include <cstddef>
1 #include <iostream>
2 #include <istream>
3 #include <memory>
4 #include <ostream>
5 #include <vector>
7 class SerializerBase {
8 static std::size_t type_count;
10 using Factory = SerializerBase *(*)(std::istream &s);
11 static std::vector<Factory> registry;
13 protected:
14 virtual void Serialize(std::ostream &s) const = 0;
16 public:
17 virtual ~SerializerBase() = default;
19 static size_t RegisterType(Factory factory) {
20 registry.emplace_back(std::move(factory));
21 return type_count++;
22 }
24 static auto Deserialize(size_t type, std::istream &s) {
25 return std::unique_ptr<SerializerBase>(registry[type](s));
26 }
27 };
29 std::vector<SerializerBase::Factory> SerializerBase::registry;
30 size_t SerializerBase::type_count = 0;
32 class DeserializerFactory {
33 std::istream &m_s;
35 public:
36 explicit DeserializerFactory(std::istream &s) : m_s(s) {}
38 template <typename It> void Deserialize(It iter) {
39 while (true) {
40 size_t type;
41 m_s >> type;
42 if (m_s.eof()) {
43 return;
44 }
45 iter = SerializerBase::Deserialize(type, m_s);
46 }
47 }
48 };
50 class Derived1 : public SerializerBase {
51 int m_i;
53 public:
54 static const size_t type_tag;
56 Derived1(int i) : m_i(i) { /* ... */ }
58 void Serialize(std::ostream &s) const override {
59 s << type_tag << ' ' << m_i << std::endl;
60 }
61 };
63 const size_t Derived1::type_tag =
64 RegisterType([](std::istream &s) -> SerializerBase * {
65 int i;
66 s >> i;
67 return new Derived1(i);
68 });
70 class Derived2 : public SerializerBase {
71 double m_x;
72 double m_y;
74 public:
75 static const size_t type_tag;
77 Derived2(double x, double y) : m_x(x), m_y(y) { /* ... */ }
79 void Serialize(std::ostream &s) const override {
80 s << type_tag << ' ' << m_x << ' ' << m_y << std::endl;
81 }
82 };
84 const size_t Derived2::type_tag =
85 RegisterType([](std::istream &s) -> SerializerBase * {
86 double x;
87 double y;
88 s >> x >> y;
89 return new Derived2(x, y);
90 });
92 class Derived3 : public SerializerBase {
93 bool m_integer;
95 int m_i;
96 double m_x;
98 public:
99 static const size_t type_tag;
101 Derived3(int i) : m_i(i) { /* ... */ }
102 Derived3(double x) : m_x(x) { /* ... */ }
104 void Serialize(std::ostream &s) const override {
105 s << type_tag << ' ' << m_integer << ' ';
106 if (m_integer) {
107 s << m_i;
108 } else {
109 s << m_x;
111 s << std::endl;
113 };
115 const size_t Derived3::type_tag =
116 RegisterType([](std::istream &s) -> SerializerBase * {
117 bool integer;
118 s >> integer;
120 if (integer) {
121 int i;
122 s >> i;
123 return new Derived3(i);
124 } else {
125 double d;
126 s >> d;
127 return new Derived3(d);
129 });
131 int main() {
132 Derived1 d(42);
133 d.Serialize(std::cout);
135 return 0;