Skip to content

Commit 84dae2c

Browse files
Better pattern
1 parent 822c3c9 commit 84dae2c

File tree

1 file changed

+162
-17
lines changed

1 file changed

+162
-17
lines changed

src/patterns.cpp

Lines changed: 162 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,202 @@
22

33
#include <cstddef>
44
#include <iostream>
5+
6+
7+
struct DummyVTable {
8+
9+
template<typename T>
10+
static DummyVTable * make_vtable() {
11+
static DummyVTable vtablet;
12+
return &vtablet;
13+
}
14+
15+
template <typename T>
16+
void bind() {}
17+
18+
};
19+
20+
21+
522
struct writable
623
{
7-
struct vtable
24+
template<typename BaseVTable = DummyVTable>
25+
struct vtable : public BaseVTable
826
{
927
int (*write)(void * obj, const char *, int);
28+
29+
template<typename T>
30+
void bind()
31+
{
32+
this->BaseVTable::template bind<T>();
33+
34+
write = [](void * obj, const char * arg0, int arg1) -> int {
35+
return static_cast<T*>(obj)->write(arg0, arg1);
36+
};
37+
}
38+
39+
public:
40+
template<typename T>
41+
static vtable * make_vtable()
42+
{
43+
static vtable<BaseVTable> vtablet;
44+
vtablet.bind<T>();
45+
46+
return &vtablet;
47+
}
1048
};
1149

12-
template <typename T>
13-
static vtable * make_vtable()
50+
struct view
1451
{
15-
static vtable vtablet;
16-
vtablet.write = [](void * obj, const char * arg0, int arg1) -> int {
17-
return static_cast<T*>(obj)->write(arg0, arg1);
18-
};
19-
return &vtablet;
52+
void * obj;
53+
vtable<> * vtbl;
54+
int write(const char * arg0, int arg1) { return vtbl->write(obj, arg0, arg1); }
55+
};
56+
57+
template<typename T>
58+
static view make_view(T & t)
59+
{
60+
view v;
61+
v.obj = static_cast<void *>(&t);
62+
v.vtbl = vtable<>::make_vtable<T>();
63+
return v;
2064
}
65+
};
66+
67+
68+
struct readable
69+
{
70+
template<typename BaseVTable = DummyVTable>
71+
struct vtable : public BaseVTable
72+
{
73+
int (*read)(void * obj, const char *, int);
74+
75+
template<typename T>
76+
void bind()
77+
{
78+
this->BaseVTable::template bind<T>();
79+
80+
read = [](void * obj, const char * arg0, int arg1) -> int {
81+
return static_cast<T*>(obj)->read(arg0, arg1);
82+
};
83+
}
84+
85+
public:
86+
template<typename T>
87+
static vtable * make_vtable()
88+
{
89+
static vtable<BaseVTable> vtablet;
90+
vtablet.bind<T>();
91+
92+
return &vtablet;
93+
}
94+
};
2195

2296
struct view
2397
{
2498
void * obj;
25-
vtable * vtbl;
26-
int write(const char * arg0, int arg1) { return vtbl->write(obj, arg0, arg1); }
99+
vtable<> * vtbl;
100+
int read(const char * arg0, int arg1) { return vtbl->read(obj, arg0, arg1); }
27101
};
28102

29103
template<typename T>
30104
static view make_view(T & t)
31105
{
32106
view v;
33107
v.obj = static_cast<void *>(&t);
34-
v.vtbl = make_vtable<T>();
108+
v.vtbl = vtable<>::make_vtable<T>();
35109
return v;
36110
}
37111
};
38112

113+
struct readwritable
114+
{
115+
template<typename BaseVTable = DummyVTable>
116+
struct vtable : public BaseVTable
117+
{
118+
int (*read)(void * obj, const char *, int);
119+
120+
template<typename T>
121+
void bind()
122+
{
123+
this->BaseVTable::template bind<T>();
124+
}
125+
126+
public:
127+
template<typename T>
128+
static vtable * make_vtable()
129+
{
130+
static vtable<BaseVTable> vtablet;
131+
vtablet.bind<T>();
132+
133+
return &vtablet;
134+
}
135+
};
136+
137+
struct view
138+
{
139+
void * obj;
140+
vtable<> * vtbl;
141+
int read(const char * arg0, int arg1) { return vtbl->read(obj, arg0, arg1); }
142+
};
143+
144+
template<typename T>
145+
static view make_view(T & t)
146+
{
147+
view v;
148+
v.obj = static_cast<void *>(&t);
149+
v.vtbl = vtable<>::make_vtable<T>();
150+
return v;
151+
}
152+
};
39153

40-
class Writer {
41-
public:
42-
int write(const char *buf, size_t size) {
154+
155+
156+
157+
158+
159+
struct AbstractWriter
160+
{
161+
virtual int write(const char *buf, size_t size) = 0;
162+
};
163+
164+
struct AbstractReader
165+
{
166+
virtual int read(char *buf, size_t size) = 0;
167+
};
168+
169+
struct DerivedWriter : public AbstractWriter
170+
{
171+
virtual int write(const char *buf, size_t size) final {
43172
int n = 0;
44-
while (size--) { std::cout << buf[n++]; }
173+
while (size--) {
174+
std::cout << buf[n++];
175+
}
45176
std::cout << std::flush;
46177
return n;
47178
}
48179
};
49180

181+
struct DerivedReadWriter : public AbstractWriter, public AbstractReader
182+
{
183+
virtual int write(const char *buf, size_t size) final {
184+
int n = 0;
185+
while (size--) {
186+
std::cout << buf[n++];
187+
}
188+
std::cout << std::flush;
189+
return n;
190+
}
191+
virtual int read(char *buf, size_t size) final {
192+
return std::fread(buf, 1, size, stdin);
193+
}
194+
};
50195

51196

52197
int main()
53198
{
54-
Writer w;
55-
writable::view v = writable::make_view(w);
199+
DerivedReadWriter wr;
200+
writable::view v = writable::make_view(wr);
56201

57202
v.write("hello\n", 7);
58203
return 0;

0 commit comments

Comments
 (0)