source: doc/generic_types/evaluation/object.hpp @ 79b8dc3

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 79b8dc3 was 79b8dc3, checked in by Aaron Moss <a3moss@…>, 4 years ago

Some compaction of benchmark code

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