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

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 87c5f40 was 87c5f40, checked in by Aaron Moss <a3moss@…>, 7 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.