source: doc/generic_types/evaluation/object.hpp @ e3de500

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since e3de500 was 3fb7f5e, checked in by Aaron Moss <a3moss@…>, 5 years ago

Update benchmarks, cleanup edits to the evaluation section

  • Property mode set to 100644
File size: 6.1 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.