source: doc/generic_types/evaluation/object.hpp@ 87c5f40

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 87c5f40 was 87c5f40, checked in by Aaron Moss <a3moss@…>, 9 years ago

Update benchmarks to include stack of pairs

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