source: doc/papers/general/evaluation/object.hpp @ 80eefcb

no_list
Last change on this file since 80eefcb was fb2ce27, checked in by Aaron Moss <a3moss@…>, 7 years ago

Update all benchmarks to match new CFA

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