source: doc/generic_types/evaluation/object.hpp @ 33e22da

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 33e22da was a381b46, checked in by Aaron Moss <a3moss@…>, 7 years ago

Minor cleanup, also filled in benchmark source appendix

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