1+ #include " archetype/archetype.h"
2+ #include < iostream>
3+ #include < cstring>
4+ #include < string>
5+ #include < vector>
6+
7+ // Define our archetypes
8+ ARCHETYPE_DEFINE (writable, (
9+ ARCHETYPE_METHOD (int , write, const char *, size_t )
10+ ))
11+
12+ ARCHETYPE_DEFINE(readable, (
13+ ARCHETYPE_METHOD (int , read, char *, size_t )
14+ ))
15+
16+ ARCHETYPE_COMPOSE(readwritable, readable, writable)
17+
18+
19+
20+ // Here is a collection of readers and writers created in different ways
21+ class Writer {
22+ public:
23+ int write (const char *buf, size_t size) {
24+ int n = 0 ;
25+ while (size--) { std::cout << buf[n++]; }
26+ std::cout << std::flush;
27+ return n;
28+ }
29+ };
30+
31+ class Reader {
32+ public:
33+ int read (char *buf, size_t size) { return std::fread (buf, 1 , size, stdin); }
34+ };
35+
36+ class InherritedReadWriter : public Writer {
37+ public:
38+ int read (char *buf, size_t size) { return std::fread (buf, 1 , size, stdin); }
39+ };
40+
41+ class NativeReadWriter {
42+ public:
43+ int read (char *buf, size_t size) { return std::fread (buf, 1 , size, stdin); }
44+ int write (const char *buf, size_t size) {
45+ int n = 0 ;
46+ while (size--) {
47+ std::cout << buf[n++];
48+ }
49+ std::cout << std::flush;
50+ return n;
51+ }
52+ };
53+
54+ class ComposedReadWriter {
55+ public:
56+ int read (char *buf, size_t size) { return reader.read (buf, size); }
57+ int write (const char *buf, size_t size) { return writer.write (buf, size); }
58+
59+ private:
60+ Writer writer;
61+ Reader reader;
62+ };
63+
64+ struct AbstractWriter
65+ {
66+ virtual int write (const char *buf, size_t size) = 0;
67+ };
68+
69+ struct AbstractReader
70+ {
71+ virtual int read (char *buf, size_t size) = 0;
72+ };
73+
74+ struct DerivedWriter : public AbstractWriter
75+ {
76+ virtual int write (const char *buf, size_t size) final {
77+ int n = 0 ;
78+ while (size--) {
79+ std::cout << buf[n++];
80+ }
81+ std::cout << std::flush;
82+ return n;
83+ }
84+ };
85+
86+ struct DerivedReadWriter : public AbstractWriter , public AbstractReader
87+ {
88+ virtual int write (const char *buf, size_t size) final {
89+ int n = 0 ;
90+ while (size--) {
91+ std::cout << buf[n++];
92+ }
93+ std::cout << std::flush;
94+ return n;
95+ }
96+ virtual int read (char *buf, size_t size) final {
97+ return std::fread (buf, 1 , size, stdin);
98+ }
99+ };
100+
101+ // Define interfaces
102+
103+
104+ // Stateless mixin read API
105+ template <typename R> struct ReadAPI : public R {
106+ ARCHETYPE_CHECK (readable, R)
107+ using R::R;
108+ using R::read;
109+ int read_api (char *buf, size_t size) { return this ->read (buf, size); }
110+ };
111+
112+
113+ // Stateful mixin APIs
114+ template <typename W> struct StatefulWriteAPI : public W {
115+ ARCHETYPE_CHECK (writable, W);
116+ using W::W;
117+ using W::write;
118+ size_t write_api (const char *buf) {
119+ std::string header = " count: " + std::to_string (count++)+ " " ;
120+ int size = this ->write (header.c_str (), header.size ());
121+ size += this ->write (buf, strlen (buf));
122+ return size;
123+ }
124+ int count = 0 ;
125+ };
126+
127+ int main ()
128+ {
129+
130+ if (__cplusplus == 202302L )
131+ std::cout << " C++23" ;
132+ else if (__cplusplus == 202002L )
133+ std::cout << " C++20" ;
134+ else if (__cplusplus == 201703L )
135+ std::cout << " C++17" ;
136+ else if (__cplusplus == 201402L )
137+ std::cout << " C++14" ;
138+ else if (__cplusplus == 201103L )
139+ std::cout << " C++11" ;
140+ else if (__cplusplus == 199711L )
141+ std::cout << " C++98" ;
142+ else
143+ std::cout << " pre-standard C++." << __cplusplus;
144+ std::cout << " \n " ;
145+
146+
147+ ComposedReadWriter composed_read_writer;
148+ NativeReadWriter native_read_writer;
149+ InherritedReadWriter inherrited_read_writer;
150+ AbstractWriter * base_ptr = new DerivedReadWriter ();
151+ std::vector<writable::view> views (4 );
152+
153+ views[0 ].bind (composed_read_writer);
154+ views[1 ].bind (native_read_writer);
155+ views[2 ].bind (inherrited_read_writer);
156+ views[3 ].bind (*base_ptr);
157+
158+ for (auto & view : views) {
159+ view.write (" hello\r\n " , 7 );
160+ }
161+
162+
163+ delete base_ptr;
164+ return 0 ;
165+
166+ }
0 commit comments