zeusUnnamed repository; edit this file 'description' to name the repository. |
git clone Unknown |
Log | Files | Refs |
commit | af6947bdb404578a8567b72ad3460c6c16e42b8e |
parent | 338aa1a5e93c6eeb615db830455e69979ee8e335 |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Sat, 17 May 2025 21:16:09 +0200 |
Visitor serialization
A | visitor_serialization.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 files changed, 179 insertions(+), 0 deletions(-)
diff --git a/ visitor_serialization.cpp b/ visitor_serialization.cpp
@@ -0,0 +1,179 @@
#include <iostream>
#include <memory>
#include <sstream>
class Visitor;
class Point;
class Circle;
class Line;
class Intersection;
class Geometry {
public:
enum class type_tag { Point = 100, Circle, Line, Intersection };
virtual ~Geometry() = default;
virtual type_tag tag() const = 0;
virtual void accept(Visitor &v) = 0;
};
class Visitor {
public:
static Geometry *make_geometry(Geometry::type_tag tag);
virtual void visit(Geometry::type_tag &tag) = 0;
virtual void visit(double &x) = 0;
virtual void visit(Point &p) = 0;
virtual void visit(Circle &c) = 0;
virtual void visit(Line &l) = 0;
virtual void visit(Intersection &i) = 0;
};
class Point : public Geometry {
double m_x;
double m_y;
public:
Point(double x, double y) : m_x(x), m_y(y) {}
Point() = default;
type_tag tag() const override { return type_tag::Point; }
void accept(Visitor &v) override {
v.visit(m_x);
v.visit(m_y);
}
};
class Circle : public Geometry {
Point m_c;
double m_r;
public:
Circle(Point c, double r) : m_c(c), m_r(r) {}
Circle() = default;
type_tag tag() const override { return type_tag::Circle; }
void accept(Visitor &v) override {
v.visit(m_c);
v.visit(m_r);
}
};
class Line : public Geometry {
Point m_p1;
Point m_p2;
public:
Line(Point p1, Point p2) : m_p1(p1), m_p2(p2) {}
Line() = default;
type_tag tag() const override { return type_tag::Line; }
void accept(Visitor &v) override {
v.visit(m_p1);
v.visit(m_p2);
}
};
class Intersection : public Geometry {
std::unique_ptr<Geometry> m_g1;
std::unique_ptr<Geometry> m_g2;
public:
Intersection(Geometry *g1, Geometry *g2) : m_g1(g1), m_g2(g2) {}
Intersection() = default;
type_tag tag() const override { return type_tag::Intersection; }
void accept(Visitor &v) override {
Geometry::type_tag tag;
if (m_g1) {
tag = m_g1->tag();
}
v.visit(tag);
if (!m_g1) {
m_g1.reset(Visitor::make_geometry(tag));
}
m_g1->accept(v);
if (m_g2) {
tag = m_g2->tag();
}
v.visit(tag);
if (!m_g2) {
m_g2.reset(Visitor::make_geometry(tag));
}
m_g2->accept(v);
}
};
Geometry *Visitor::make_geometry(Geometry::type_tag tag) {
switch (tag) {
case Geometry::type_tag::Point:
return new Point;
case Geometry::type_tag::Circle:
return new Circle;
case Geometry::type_tag::Line:
return new Line;
case Geometry::type_tag::Intersection:
return new Intersection;
}
}
class StringSerializeVisitor : public Visitor {
std::stringstream m_s;
public:
[[nodiscard]] std::string str() const { return m_s.str(); }
void visit(Geometry::type_tag &tag) override { m_s << size_t(tag) << " "; }
void visit(double &x) override { m_s << x << " "; }
void visit(Point &p) override { p.accept(*this); }
void visit(Circle &c) override { c.accept(*this); }
void visit(Line &l) override { l.accept(*this); }
void visit(Intersection &i) override { i.accept(*this); }
};
class StringDeserializeVisitor : public Visitor {
std::stringstream m_s;
public:
StringDeserializeVisitor(const std::string &s) : m_s(s) {}
[[nodiscard]] std::string str() const { return m_s.str(); }
void visit(Geometry::type_tag &tag) override {
size_t t;
m_s >> t;
tag = Geometry::type_tag(t);
}
void visit(double &x) override { m_s >> x; }
void visit(Point &p) override { p.accept(*this); }
void visit(Circle &c) override { c.accept(*this); }
void visit(Line &l) override { l.accept(*this); }
void visit(Intersection &i) override { i.accept(*this); }
};
int main() {
Intersection i(new Line({1, 1}, {4, 4}), new Circle({0, 0}, 4));
StringSerializeVisitor serializer;
serializer.visit(i);
std::cout << serializer.str() << std::endl;
StringDeserializeVisitor deserializer(serializer.str());
Intersection i1;
deserializer.visit(i1);
}