zeusUnnamed repository; edit this file 'description' to name the repository. |
git clone Unknown |
Log | Files | Refs |
visitor_serialization.cpp (3895B)
0 #include <iostream>
1 #include <memory>
2 #include <sstream>
4 class Visitor;
6 class Point;
7 class Circle;
8 class Line;
9 class Intersection;
11 class Geometry {
12 public:
13 enum class type_tag { Point = 100, Circle, Line, Intersection };
15 virtual ~Geometry() = default;
17 virtual type_tag tag() const = 0;
19 virtual void accept(Visitor &v) = 0;
20 };
22 class Visitor {
23 public:
24 static Geometry *make_geometry(Geometry::type_tag tag);
26 virtual void visit(Geometry::type_tag &tag) = 0;
28 virtual void visit(double &x) = 0;
29 virtual void visit(Point &p) = 0;
30 virtual void visit(Circle &c) = 0;
31 virtual void visit(Line &l) = 0;
32 virtual void visit(Intersection &i) = 0;
33 };
35 class Point : public Geometry {
36 double m_x;
37 double m_y;
39 public:
40 Point(double x, double y) : m_x(x), m_y(y) {}
41 Point() = default;
43 type_tag tag() const override { return type_tag::Point; }
45 void accept(Visitor &v) override {
46 v.visit(m_x);
47 v.visit(m_y);
48 }
49 };
51 class Circle : public Geometry {
52 Point m_c;
53 double m_r;
55 public:
56 Circle(Point c, double r) : m_c(c), m_r(r) {}
57 Circle() = default;
59 type_tag tag() const override { return type_tag::Circle; }
61 void accept(Visitor &v) override {
62 v.visit(m_c);
63 v.visit(m_r);
64 }
65 };
67 class Line : public Geometry {
68 Point m_p1;
69 Point m_p2;
71 public:
72 Line(Point p1, Point p2) : m_p1(p1), m_p2(p2) {}
73 Line() = default;
75 type_tag tag() const override { return type_tag::Line; }
77 void accept(Visitor &v) override {
78 v.visit(m_p1);
79 v.visit(m_p2);
80 }
81 };
83 class Intersection : public Geometry {
84 std::unique_ptr<Geometry> m_g1;
85 std::unique_ptr<Geometry> m_g2;
87 public:
88 Intersection(Geometry *g1, Geometry *g2) : m_g1(g1), m_g2(g2) {}
89 Intersection() = default;
91 type_tag tag() const override { return type_tag::Intersection; }
93 void accept(Visitor &v) override {
94 Geometry::type_tag tag;
96 if (m_g1) {
97 tag = m_g1->tag();
98 }
99 v.visit(tag);
100 if (!m_g1) {
101 m_g1.reset(Visitor::make_geometry(tag));
102 }
103 m_g1->accept(v);
105 if (m_g2) {
106 tag = m_g2->tag();
107 }
108 v.visit(tag);
109 if (!m_g2) {
110 m_g2.reset(Visitor::make_geometry(tag));
111 }
112 m_g2->accept(v);
113 }
114 };
116 Geometry *Visitor::make_geometry(Geometry::type_tag tag) {
117 switch (tag) {
118 case Geometry::type_tag::Point:
119 return new Point;
120 case Geometry::type_tag::Circle:
121 return new Circle;
122 case Geometry::type_tag::Line:
123 return new Line;
124 case Geometry::type_tag::Intersection:
125 return new Intersection;
126 }
127 }
129 class StringSerializeVisitor : public Visitor {
130 std::stringstream m_s;
132 public:
133 [[nodiscard]] std::string str() const { return m_s.str(); }
135 void visit(Geometry::type_tag &tag) override { m_s << size_t(tag) << " "; }
137 void visit(double &x) override { m_s << x << " "; }
138 void visit(Point &p) override { p.accept(*this); }
139 void visit(Circle &c) override { c.accept(*this); }
140 void visit(Line &l) override { l.accept(*this); }
141 void visit(Intersection &i) override { i.accept(*this); }
142 };
144 class StringDeserializeVisitor : public Visitor {
145 std::stringstream m_s;
147 public:
148 StringDeserializeVisitor(const std::string &s) : m_s(s) {}
150 [[nodiscard]] std::string str() const { return m_s.str(); }
152 void visit(Geometry::type_tag &tag) override {
153 size_t t;
154 m_s >> t;
155 tag = Geometry::type_tag(t);
156 }
158 void visit(double &x) override { m_s >> x; }
159 void visit(Point &p) override { p.accept(*this); }
160 void visit(Circle &c) override { c.accept(*this); }
161 void visit(Line &l) override { l.accept(*this); }
162 void visit(Intersection &i) override { i.accept(*this); }
163 };
165 int main() {
166 Intersection i(new Line({1, 1}, {4, 4}), new Circle({0, 0}, 4));
168 StringSerializeVisitor serializer;
169 serializer.visit(i);
171 std::cout << serializer.str() << std::endl;
173 StringDeserializeVisitor deserializer(serializer.str());
175 Intersection i1;
177 deserializer.visit(i1);
178 }