source: doc/generic_types/evaluation/object.hpp@ 0d10090

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 0d10090 was 0d10090, checked in by Aaron Moss <a3moss@…>, 9 years ago

Add printing code to benchmark

  • Property mode set to 100644
File size: 6.0 KB
Line 
1#pragma once
2
3#include <cstddef>
4#include <exception>
5#include <iomanip>
6#include <memory>
7#include <ostream>
8#include <string>
9#include <typeinfo>
10#include <typeindex>
11
12class bad_cast : public std::exception {
13 std::string why;
14public:
15 bad_cast( const std::type_index& f, const std::type_index& t ) : std::exception() {
16 why = std::string{"bad cast of "} + f.name() + " to " + t.name();
17 }
18
19 ~bad_cast() override = default;
20
21 const char* what() const noexcept override { return why.c_str(); }
22};
23
24template<typename T>
25std::type_index class_of() { return { typeid(T) }; }
26
27class object {
28public:
29 std::type_index get_class() const { return { this ? typeid(*this) : typeid(std::nullptr_t) }; }
30
31 template<typename T>
32 T& as() {
33 T* p = dynamic_cast<T*>(this);
34 if ( !p ) throw bad_cast{ get_class(), class_of<T>() };
35 return *p;
36 }
37
38 template<typename T>
39 const T& as() const {
40 const T* p = dynamic_cast<const T*>(this);
41 if ( !p ) throw bad_cast{ get_class(), class_of<T>() };
42 return *p;
43 }
44
45 virtual std::unique_ptr<object> new_inst() const = 0;
46
47 virtual std::unique_ptr<object> new_copy() const = 0;
48
49 virtual object& operator= (const object&) = 0;
50
51 virtual ~object() = default;
52};
53
54template<typename To, typename From>
55std::unique_ptr<To> as_ptr( std::unique_ptr<From>&& p ) {
56 return std::unique_ptr<To>{ &p.release()->template as<To>() };
57}
58
59class ordered : public virtual object {
60public:
61 virtual int cmp(const ordered&) const = 0;
62
63 bool operator< (const ordered& that) const { return cmp(that) < 0; }
64
65 bool operator<= ( const ordered& that ) const { return cmp(that) <= 0; }
66
67 bool operator== ( const ordered& that ) const { return cmp(that) == 0; }
68
69 bool operator!= ( const ordered& that ) const { return cmp(that) != 0; }
70
71 bool operator> ( const ordered& that ) const { return cmp(that) > 0; }
72
73 bool operator>= ( const ordered& that ) const { return cmp(that) >= 0; }
74};
75
76class printable : public virtual object {
77public:
78 virtual void print(std::ostream&) const = 0;
79};
80
81class boolean : public ordered, public printable {
82 bool x;
83
84public:
85 boolean() = default;
86
87 boolean(bool x) : x(x) {}
88
89 std::unique_ptr<object> new_inst() const override { return std::make_unique<boolean>(); }
90
91 std::unique_ptr<object> new_copy() const override { return std::make_unique<boolean>(*this); }
92
93 boolean& operator= (const boolean& that) {
94 x = that.x;
95 return *this;
96 }
97
98 object& operator= (const object& that) override { return *this = that.as<boolean>(); }
99
100 ~boolean() override = default;
101
102 int cmp(const boolean& that) const { return x == that.x ? 0 : x == false ? -1 : 1; }
103
104 int cmp(const ordered& that) const override { return cmp( that.as<boolean>() ); }
105
106 void print(std::ostream& out) const override { out << (x ? "true" : "false"); }
107};
108
109class character : public ordered, public printable {
110 char x;
111
112public:
113 character() = default;
114
115 character(char x) : x(x) {}
116
117 std::unique_ptr<object> new_inst() const override { return std::make_unique<character>(); }
118
119 std::unique_ptr<object> new_copy() const override { return std::make_unique<character>(*this); }
120
121 character& operator= (const character& that) {
122 x = that.x;
123 return *this;
124 }
125
126 object& operator= (const object& that) override { return *this = that.as<character>(); }
127
128 ~character() override = default;
129
130 int cmp(const character& that) const { return x == that.x ? 0 : x < that.x ? -1 : 1; }
131
132 int cmp(const ordered& that) const override { return cmp( that.as<character>() ); }
133
134 void print(std::ostream& out) const override {
135 if ( 0x20 <= x && x <= 0x7E ) { out << "'" << x << "'"; }
136 else { out << "'\\" << std::hex << (unsigned int)x << std::setbase(0) << "'"; }
137 }
138};
139
140class integer : public ordered, public printable {
141 int x;
142
143public:
144 integer() = default;
145
146 integer(int x) : x(x) {}
147
148 std::unique_ptr<object> new_inst() const override { return std::make_unique<integer>(); }
149
150 std::unique_ptr<object> new_copy() const override { return std::make_unique<integer>(*this); }
151
152 integer& operator= (const integer& that) {
153 x = that.x;
154 return *this;
155 }
156
157 object& operator= (const object& that) override { return *this = that.as<integer>(); }
158
159 ~integer() override = default;
160
161 int cmp(const integer& that) const { return x == that.x ? 0 : x < that.x ? -1 : 1; }
162
163 int cmp(const ordered& that) const override { return cmp( that.as<integer>() ); }
164
165 void print(std::ostream& out) const override { out << x; }
166};
167
168class c_string : public printable {
169 static constexpr const char* empty = "";
170 const char* s;
171public:
172 c_string() : s(empty) {}
173
174 c_string(const char* s) : s(s) {}
175
176 std::unique_ptr<object> new_inst() const override { return std::make_unique<c_string>(); }
177
178 std::unique_ptr<object> new_copy() const override { return std::make_unique<c_string>(s); }
179
180 c_string& operator= (const c_string& that) {
181 s = that.s;
182 return *this;
183 }
184
185 object& operator= (const object& that) override { return *this = that.as<c_string>(); }
186
187 ~c_string() override = default;
188
189 void print(std::ostream& out) const override { out << s; }
190};
191
192class pair : public ordered, public printable {
193 std::unique_ptr<object> x;
194 std::unique_ptr<object> y;
195
196public:
197 pair() = default;
198
199 pair(std::unique_ptr<object>&& x, std::unique_ptr<object>&& y)
200 : x(std::move(x)), y(std::move(y)) {}
201
202 std::unique_ptr<object> new_inst() const override { return std::make_unique<pair>(); }
203
204 std::unique_ptr<object> new_copy() const override {
205 return std::make_unique<pair>(x->new_copy(), y->new_copy());
206 }
207
208 pair& operator= (const pair& that) {
209 x = that.x->new_copy();
210 y = that.y->new_copy();
211 return *this;
212 }
213
214 object& operator= (const object& that) override { return *this = that.as<pair>(); }
215
216 ~pair() override = default;
217
218 int cmp(const pair& that) const {
219 int c = x->as<ordered>().cmp( that.x->as<ordered>() );
220 if ( c != 0 ) return c;
221 return y->as<ordered>().cmp( that.y->as<ordered>() );
222 }
223
224 int cmp(const ordered& that) const override { return cmp( that.as<pair>() ); }
225
226 void print(std::ostream& out) const override {
227 out << "[";
228 x->as<printable>().print(out);
229 out << ", ";
230 y->as<printable>().print(out);
231 out << "]";
232 }
233};
Note: See TracBrowser for help on using the repository browser.