zeusUnnamed repository; edit this file 'description' to name the repository. |
git clone Unknown |
Log | Files | Refs |
commit | aa505b60b28bf9baaaa6df40fe24ebcb9d743f22 |
parent | 70a52be7e4bd76dfac7397ab7d33de06f08a7c83 |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Mon, 12 May 2025 19:21:23 +0200 |
Factory serialization
A | factory_serialization.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 files changed, 137 insertions(+), 0 deletions(-)
diff --git a/ factory_serialization.cpp b/ factory_serialization.cpp
@@ -0,0 +1,137 @@
#include <cstddef>
#include <iostream>
#include <istream>
#include <memory>
#include <ostream>
#include <vector>
class SerializerBase {
static std::size_t type_count;
using Factory = SerializerBase *(*)(std::istream &s);
static std::vector<Factory> registry;
protected:
virtual void Serialize(std::ostream &s) const = 0;
public:
virtual ~SerializerBase() = default;
static size_t RegisterType(Factory factory) {
registry.emplace_back(std::move(factory));
return type_count++;
}
static auto Deserialize(size_t type, std::istream &s) {
return std::unique_ptr<SerializerBase>(registry[type](s));
}
};
std::vector<SerializerBase::Factory> SerializerBase::registry;
size_t SerializerBase::type_count = 0;
class DeserializerFactory {
std::istream &m_s;
public:
explicit DeserializerFactory(std::istream &s) : m_s(s) {}
template <typename It> void Deserialize(It iter) {
while (true) {
size_t type;
m_s >> type;
if (m_s.eof()) {
return;
}
iter = SerializerBase::Deserialize(type, m_s);
}
}
};
class Derived1 : public SerializerBase {
int m_i;
public:
static const size_t type_tag;
Derived1(int i) : m_i(i) { /* ... */ }
void Serialize(std::ostream &s) const override {
s << type_tag << ' ' << m_i << std::endl;
}
};
const size_t Derived1::type_tag =
RegisterType([](std::istream &s) -> SerializerBase * {
int i;
s >> i;
return new Derived1(i);
});
class Derived2 : public SerializerBase {
double m_x;
double m_y;
public:
static const size_t type_tag;
Derived2(double x, double y) : m_x(x), m_y(y) { /* ... */ }
void Serialize(std::ostream &s) const override {
s << type_tag << ' ' << m_x << ' ' << m_y << std::endl;
}
};
const size_t Derived2::type_tag =
RegisterType([](std::istream &s) -> SerializerBase * {
double x;
double y;
s >> x >> y;
return new Derived2(x, y);
});
class Derived3 : public SerializerBase {
bool m_integer;
int m_i;
double m_x;
public:
static const size_t type_tag;
Derived3(int i) : m_i(i) { /* ... */ }
Derived3(double x) : m_x(x) { /* ... */ }
void Serialize(std::ostream &s) const override {
s << type_tag << ' ' << m_integer << ' ';
if (m_integer) {
s << m_i;
} else {
s << m_x;
}
s << std::endl;
}
};
const size_t Derived3::type_tag =
RegisterType([](std::istream &s) -> SerializerBase * {
bool integer;
s >> integer;
if (integer) {
int i;
s >> i;
return new Derived3(i);
} else {
double d;
s >> d;
return new Derived3(d);
}
});
int main() {
Derived1 d(42);
d.Serialize(std::cout);
return 0;
}