git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: runtime cleanup
cde8c4cAndy Arvanitis
pcc/include/purescript.cc+47−47
@@ -22,32 +22,32 @@ any::any(const any& val) : type(val.type) {
22 case Type::Double: d = val.d; break;
22 case Type::Double: d = val.d; break;
23 case Type::Character: c = val.c; break;
23 case Type::Character: c = val.c; break;
24 case Type::Boolean: b = val.b; break;
24 case Type::Boolean: b = val.b; break;
25− case Type::String: new (&s) shared_string (val.s); break;
25+ case Type::String: new (&s) shared<string> (val.s); break;
26− case Type::Map: new (&m) shared_map (val.m); break;
26+ case Type::Map: new (&m) shared<map> (val.m); break;
27− case Type::Vector: new (&v) shared_vector (val.v); break;
27+ case Type::Vector: new (&v) shared<vector> (val.v); break;
28− case Type::Function: new (&f) shared_fn (val.f); break;
28+ case Type::Function: new (&f) shared<fn> (val.f); break;
29− case Type::EffFunction: new (&e) shared_eff_fn (val.e); break;
29+ case Type::EffFunction: new (&e) shared<eff_fn> (val.e); break;
30− case Type::Thunk: new (&t) shared_thunk (val.t); break;
30+ case Type::Thunk: new (&t) shared<thunk> (val.t); break;
31− case Type::Pointer: new (&p) shared_void_ptr (val.p); break;
31+ case Type::Pointer: new (&p) shared<void> (val.p); break;
32
32
33 default: assert(false && "Unsupported type in copy ctor");
33 default: assert(false && "Unsupported type in copy ctor");
34 }
34 }
35}
35}
36
36
37−void any::swap(any&& val) {
37+void any::swap(any&& val) const {
38 type = val.type;
38 type = val.type;
39 switch (type) {
39 switch (type) {
40 case Type::Integer: i = val.i; break;
40 case Type::Integer: i = val.i; break;
41 case Type::Double: d = val.d; break;
41 case Type::Double: d = val.d; break;
42 case Type::Character: c = val.c; break;
42 case Type::Character: c = val.c; break;
43 case Type::Boolean: b = val.b; break;
43 case Type::Boolean: b = val.b; break;
44− case Type::String: new (&s) shared_string (std::move(val.s)); break;
44+ case Type::String: new (&s) shared<string> (std::move(val.s)); break;
45− case Type::Map: new (&m) shared_map (std::move(val.m)); break;
45+ case Type::Map: new (&m) shared<map> (std::move(val.m)); break;
46− case Type::Vector: new (&v) shared_vector (std::move(val.v)); break;
46+ case Type::Vector: new (&v) shared<vector> (std::move(val.v)); break;
47− case Type::Function: new (&f) shared_fn (std::move(val.f)); break;
47+ case Type::Function: new (&f) shared<fn> (std::move(val.f)); break;
48− case Type::EffFunction: new (&e) shared_eff_fn (std::move(val.e)); break;
48+ case Type::EffFunction: new (&e) shared<eff_fn> (std::move(val.e)); break;
49− case Type::Thunk: new (&t) shared_thunk (std::move(val.t)); break;
49+ case Type::Thunk: new (&t) shared<thunk> (std::move(val.t)); break;
50− case Type::Pointer: new (&p) shared_void_ptr (std::move(val.p)); break;
50+ case Type::Pointer: new (&p) shared<void> (std::move(val.p)); break;
51
51
52 default: assert(false && "Unsupported type in move ctor");
52 default: assert(false && "Unsupported type in move ctor");
53 }
53 }
@@ -60,13 +60,13 @@ any::~any() {
60 case Type::Double: ; break;
60 case Type::Double: ; break;
61 case Type::Character: ; break;
61 case Type::Character: ; break;
62 case Type::Boolean: ; break;
62 case Type::Boolean: ; break;
63− case Type::String: s.~shared_string(); break;
63+ case Type::String: s.~shared<string>(); break;
64− case Type::Map: m.~shared_map(); break;
64+ case Type::Map: m.~shared<map>(); break;
65− case Type::Vector: v.~shared_vector(); break;
65+ case Type::Vector: v.~shared<vector>(); break;
66− case Type::Function: f.~shared_fn(); break;
66+ case Type::Function: f.~shared<fn>(); break;
67− case Type::EffFunction: e.~shared_eff_fn(); break;
67+ case Type::EffFunction: e.~shared<eff_fn>(); break;
68− case Type::Thunk: t.~shared_thunk(); break;
68+ case Type::Thunk: t.~shared<thunk>(); break;
69− case Type::Pointer: p.~shared_void_ptr(); break;
69+ case Type::Pointer: p.~shared<void>(); break;
70
70
71 default: assert(false && "Unsupported type in destructor");
71 default: assert(false && "Unsupported type in destructor");
72 }
72 }
@@ -229,21 +229,21 @@ any::~any() {
229
229
230#define DEFINE_OPERATOR_LHS(K, T, OP, V, R, P) \
230#define DEFINE_OPERATOR_LHS(K, T, OP, V, R, P) \
231auto operator OP(const T lhs, const any& rhs_) -> R { \
231auto operator OP(const T lhs, const any& rhs_) -> R { \
232− auto& rhs = any::extract_value(rhs_); \
232+ const any& rhs = any::extract_value(rhs_); \
233 assert(rhs.type == any::Type::K); \
233 assert(rhs.type == any::Type::K); \
234 return lhs OP P(rhs.V); \
234 return lhs OP P(rhs.V); \
235}
235}
236
236
237#define DEFINE_OPERATOR_RHS(K, T, OP, V, R, P) \
237#define DEFINE_OPERATOR_RHS(K, T, OP, V, R, P) \
238auto any::operator OP(const T rhs) const -> R { \
238auto any::operator OP(const T rhs) const -> R { \
239− auto& lhs = any::extract_value(*this); \
239+ const any& lhs = any::extract_value(*this); \
240 assert(lhs.type == Type::K); \
240 assert(lhs.type == Type::K); \
241 return P(lhs.V) OP rhs; \
241 return P(lhs.V) OP rhs; \
242}
242}
243
243
244auto any::operator==(const any& rhs_) const -> bool {
244auto any::operator==(const any& rhs_) const -> bool {
245− auto& lhs = extract_value(*this);
245+ const any& lhs = extract_value(*this);
246− auto& rhs = extract_value(rhs_);
246+ const any& rhs = extract_value(rhs_);
247 assert(lhs.type == rhs.type);
247 assert(lhs.type == rhs.type);
248 switch (lhs.type) {
248 switch (lhs.type) {
249 case Type::Integer: return lhs.i == rhs.i;
249 case Type::Integer: return lhs.i == rhs.i;
@@ -265,8 +265,8 @@ DEFINE_OPERATOR_RHS(String, string&, ==, s, bool, *)
265DEFINE_OPERATOR_RHS(String, char* const, ==, s, bool, *)
265DEFINE_OPERATOR_RHS(String, char* const, ==, s, bool, *)
266
266
267auto any::operator!=(const any& rhs_) const -> bool {
267auto any::operator!=(const any& rhs_) const -> bool {
268− auto& lhs = extract_value(*this);
268+ const any& lhs = extract_value(*this);
269− auto& rhs = extract_value(rhs_);
269+ const any& rhs = extract_value(rhs_);
270 assert(lhs.type == rhs.type);
270 assert(lhs.type == rhs.type);
271 switch (lhs.type) {
271 switch (lhs.type) {
272 case Type::Integer: return lhs.i != rhs.i;
272 case Type::Integer: return lhs.i != rhs.i;
@@ -288,8 +288,8 @@ DEFINE_OPERATOR_RHS(String, string&, !=, s, bool, *)
288DEFINE_OPERATOR_RHS(String, char* const, !=, s, bool, *)
288DEFINE_OPERATOR_RHS(String, char* const, !=, s, bool, *)
289
289
290auto any::operator<(const any& rhs_) const -> bool {
290auto any::operator<(const any& rhs_) const -> bool {
291− auto& lhs = extract_value(*this);
291+ const any& lhs = extract_value(*this);
292− auto& rhs = extract_value(rhs_);
292+ const any& rhs = extract_value(rhs_);
293 assert(lhs.type == rhs.type);
293 assert(lhs.type == rhs.type);
294 switch (lhs.type) {
294 switch (lhs.type) {
295 case Type::Integer: return lhs.i < rhs.i;
295 case Type::Integer: return lhs.i < rhs.i;
@@ -310,8 +310,8 @@ DEFINE_OPERATOR_RHS(String, string&, <, s, bool, *)
310DEFINE_OPERATOR_RHS(String, char* const, <, s, bool, *)
310DEFINE_OPERATOR_RHS(String, char* const, <, s, bool, *)
311
311
312auto any::operator<=(const any& rhs_) const -> bool {
312auto any::operator<=(const any& rhs_) const -> bool {
313− auto& lhs = extract_value(*this);
313+ const any& lhs = extract_value(*this);
314− auto& rhs = extract_value(rhs_);
314+ const any& rhs = extract_value(rhs_);
315 assert(lhs.type == rhs.type);
315 assert(lhs.type == rhs.type);
316 switch (lhs.type) {
316 switch (lhs.type) {
317 case Type::Integer: return lhs.i <= rhs.i;
317 case Type::Integer: return lhs.i <= rhs.i;
@@ -332,8 +332,8 @@ DEFINE_OPERATOR_RHS(String, string&, <=, s, bool, *)
332DEFINE_OPERATOR_RHS(String, char* const, <=, s, bool, *)
332DEFINE_OPERATOR_RHS(String, char* const, <=, s, bool, *)
333
333
334auto any::operator>(const any& rhs_) const -> bool {
334auto any::operator>(const any& rhs_) const -> bool {
335− auto& lhs = extract_value(*this);
335+ const any& lhs = extract_value(*this);
336− auto& rhs = extract_value(rhs_);
336+ const any& rhs = extract_value(rhs_);
337 assert(lhs.type == rhs.type);
337 assert(lhs.type == rhs.type);
338 switch (lhs.type) {
338 switch (lhs.type) {
339 case Type::Integer: return lhs.i > rhs.i;
339 case Type::Integer: return lhs.i > rhs.i;
@@ -354,8 +354,8 @@ DEFINE_OPERATOR_RHS(String, string&, >, s, bool, *)
354DEFINE_OPERATOR_RHS(String, char* const, >, s, bool, *)
354DEFINE_OPERATOR_RHS(String, char* const, >, s, bool, *)
355
355
356auto any::operator>=(const any& rhs_) const -> bool {
356auto any::operator>=(const any& rhs_) const -> bool {
357− auto& lhs = extract_value(*this);
357+ const any& lhs = extract_value(*this);
358− auto& rhs = extract_value(rhs_);
358+ const any& rhs = extract_value(rhs_);
359 assert(lhs.type == rhs.type);
359 assert(lhs.type == rhs.type);
360 switch (lhs.type) {
360 switch (lhs.type) {
361 case Type::Integer: return lhs.i >= rhs.i;
361 case Type::Integer: return lhs.i >= rhs.i;
@@ -376,8 +376,8 @@ DEFINE_OPERATOR_RHS(String, string&, >=, s, bool, *)
376DEFINE_OPERATOR_RHS(String, char* const, >=, s, bool, *)
376DEFINE_OPERATOR_RHS(String, char* const, >=, s, bool, *)
377
377
378auto any::operator+(const any& rhs_) const -> any {
378auto any::operator+(const any& rhs_) const -> any {
379− auto& lhs = extract_value(*this);
379+ const any& lhs = extract_value(*this);
380− auto& rhs = extract_value(rhs_);
380+ const any& rhs = extract_value(rhs_);
381 assert(lhs.type == rhs.type);
381 assert(lhs.type == rhs.type);
382 switch (lhs.type) {
382 switch (lhs.type) {
383 case Type::Integer: return lhs.i + rhs.i;
383 case Type::Integer: return lhs.i + rhs.i;
@@ -396,8 +396,8 @@ DEFINE_OPERATOR_RHS(String, string&, +, s, string, *)
396DEFINE_OPERATOR_RHS(String, char* const, +, s, string, *)
396DEFINE_OPERATOR_RHS(String, char* const, +, s, string, *)
397
397
398auto any::operator-(const any& rhs_) const -> any {
398auto any::operator-(const any& rhs_) const -> any {
399− auto& lhs = extract_value(*this);
399+ const any& lhs = extract_value(*this);
400− auto& rhs = extract_value(rhs_);
400+ const any& rhs = extract_value(rhs_);
401 assert(lhs.type == rhs.type);
401 assert(lhs.type == rhs.type);
402 switch (lhs.type) {
402 switch (lhs.type) {
403 case Type::Integer: return lhs.i - rhs.i;
403 case Type::Integer: return lhs.i - rhs.i;
@@ -413,8 +413,8 @@ DEFINE_OPERATOR_RHS(Double, double, -, d, double,)
413DEFINE_OPERATOR_RHS(Character, char, -, c, char,)
413DEFINE_OPERATOR_RHS(Character, char, -, c, char,)
414
414
415auto any::operator*(const any& rhs_) const -> any {
415auto any::operator*(const any& rhs_) const -> any {
416− auto& lhs = extract_value(*this);
416+ const any& lhs = extract_value(*this);
417− auto& rhs = extract_value(rhs_);
417+ const any& rhs = extract_value(rhs_);
418 assert(lhs.type == rhs.type);
418 assert(lhs.type == rhs.type);
419 switch (lhs.type) {
419 switch (lhs.type) {
420 case Type::Integer: return lhs.i * rhs.i;
420 case Type::Integer: return lhs.i * rhs.i;
@@ -428,8 +428,8 @@ DEFINE_OPERATOR_RHS(Integer, long, *, i, long,)
428DEFINE_OPERATOR_RHS(Double, double, *, d, double,)
428DEFINE_OPERATOR_RHS(Double, double, *, d, double,)
429
429
430auto any::operator/(const any& rhs_) const -> any {
430auto any::operator/(const any& rhs_) const -> any {
431− auto& lhs = extract_value(*this);
431+ const any& lhs = extract_value(*this);
432− auto& rhs = extract_value(rhs_);
432+ const any& rhs = extract_value(rhs_);
433 assert(lhs.type == rhs.type);
433 assert(lhs.type == rhs.type);
434 switch (lhs.type) {
434 switch (lhs.type) {
435 case Type::Integer: return lhs.i / rhs.i;
435 case Type::Integer: return lhs.i / rhs.i;
@@ -443,8 +443,8 @@ DEFINE_OPERATOR_RHS(Integer, long, /, i, long,)
443DEFINE_OPERATOR_RHS(Double, double, /, d, double,)
443DEFINE_OPERATOR_RHS(Double, double, /, d, double,)
444
444
445auto any::operator%(const any& rhs_) const -> any {
445auto any::operator%(const any& rhs_) const -> any {
446− auto& lhs = extract_value(*this);
446+ const any& lhs = extract_value(*this);
447− auto& rhs = extract_value(rhs_);
447+ const any& rhs = extract_value(rhs_);
448 assert(lhs.type == rhs.type);
448 assert(lhs.type == rhs.type);
449 switch (lhs.type) {
449 switch (lhs.type) {
450 case Type::Integer: return lhs.i % rhs.i;
450 case Type::Integer: return lhs.i % rhs.i;
@@ -456,7 +456,7 @@ auto any::operator%(const any& rhs_) const -> any {
456DEFINE_OPERATOR_RHS(Integer, long, %, i, long,)
456DEFINE_OPERATOR_RHS(Integer, long, %, i, long,)
457
457
458auto any::operator-() const -> any {
458auto any::operator-() const -> any {
459− auto& lhs = any::extract_value(*this);
459+ const any& lhs = any::extract_value(*this);
460 switch (lhs.type) {
460 switch (lhs.type) {
461 case Type::Integer: return (- lhs.i);
461 case Type::Integer: return (- lhs.i);
462 case Type::Double: return (- lhs.d);
462 case Type::Double: return (- lhs.d);
pcc/include/purescript.hh+28−38
@@ -63,7 +63,7 @@ class any {
63 Pointer
63 Pointer
64 };
64 };
65
65
66− Type type = Type::Unknown;
66+ mutable Type type = Type::Unknown;
67
67
68 struct as_thunk {
68 struct as_thunk {
69 };
69 };
@@ -75,19 +75,9 @@ class any {
75 using eff_fn = std::function<any()>;
75 using eff_fn = std::function<any()>;
76 using thunk = std::function<const any& (const as_thunk)>;
76 using thunk = std::function<const any& (const as_thunk)>;
77
77
78− using shared_string = std::shared_ptr<string>;
79− using shared_map = std::shared_ptr<map>;
80− using shared_vector = std::shared_ptr<vector>;
81−
82− using shared_fn = std::shared_ptr<fn>;
83− using shared_eff_fn = std::shared_ptr<eff_fn>;
84− using shared_thunk = std::shared_ptr<thunk>;
85−
86 template <typename T>
78 template <typename T>
87 using shared = std::shared_ptr<T>;
79 using shared = std::shared_ptr<T>;
88
80
89− using shared_void_ptr = std::shared_ptr<void>;
90−
91 template <typename T>
81 template <typename T>
92 static constexpr auto make_shared(const T& arg) -> shared<T> {
82 static constexpr auto make_shared(const T& arg) -> shared<T> {
93 return std::make_shared<T>(arg);
83 return std::make_shared<T>(arg);
@@ -105,17 +95,17 @@ class any {
105
95
106 private:
96 private:
107 union {
97 union {
108− long i;
98+ mutable long i;
109− double d;
99+ mutable double d;
110− char c;
100+ mutable char c;
111− bool b;
101+ mutable bool b;
112− shared_string s;
102+ mutable shared<string> s;
113− shared_map m;
103+ mutable shared<map> m;
114− shared_vector v;
104+ mutable shared<vector> v;
115− shared_fn f;
105+ mutable shared<fn> f;
116− shared_eff_fn e;
106+ mutable shared<eff_fn> e;
117− shared_thunk t;
107+ mutable shared<thunk> t;
118− shared_void_ptr p;
108+ mutable shared<void> p;
119 };
109 };
120
110
121 public:
111 public:
@@ -135,23 +125,23 @@ class any {
135
125
136 any(const char val[]) : type(Type::String), s(make_shared<string>(val)) {}
126 any(const char val[]) : type(Type::String), s(make_shared<string>(val)) {}
137
127
138− any(const shared_string& val) : type(Type::String), s(val) {}
128+ any(const shared<string>& val) : type(Type::String), s(val) {}
139− any(shared_string&& val) : type(Type::String), s(std::move(val)) {}
129+ any(shared<string>&& val) : type(Type::String), s(std::move(val)) {}
140
130
141 any(const map& val) : type(Type::Map), m(make_shared<map>(val)) {}
131 any(const map& val) : type(Type::Map), m(make_shared<map>(val)) {}
142 any(map&& val) : type(Type::Map), m(make_shared<map>(std::move(val))) {}
132 any(map&& val) : type(Type::Map), m(make_shared<map>(std::move(val))) {}
143
133
144− any(const shared_map& val) : type(Type::Map), m(val) {}
134+ any(const shared<map>& val) : type(Type::Map), m(val) {}
145− any(shared_map&& val) : type(Type::Map), m(std::move(val)) {}
135+ any(shared<map>&& val) : type(Type::Map), m(std::move(val)) {}
146
136
147 any(const vector& val) : type(Type::Vector), v(make_shared<vector>(val)) {}
137 any(const vector& val) : type(Type::Vector), v(make_shared<vector>(val)) {}
148 any(vector&& val) : type(Type::Vector), v(make_shared<vector>(std::move(val))) {}
138 any(vector&& val) : type(Type::Vector), v(make_shared<vector>(std::move(val))) {}
149
139
150− any(const shared_vector& val) : type(Type::Vector), v(val) {}
140+ any(const shared<vector>& val) : type(Type::Vector), v(val) {}
151− any(shared_vector&& val) : type(Type::Vector), v(std::move(val)) {}
141+ any(shared<vector>&& val) : type(Type::Vector), v(std::move(val)) {}
152
142
153− any(const shared_fn& val) : type(Type::Function), f(val) {}
143+ any(const shared<fn>& val) : type(Type::Function), f(val) {}
154− any(shared_fn&& val) : type(Type::Function), f(std::move(val)) {}
144+ any(shared<fn>&& val) : type(Type::Function), f(std::move(val)) {}
155
145
156 template <typename T>
146 template <typename T>
157 any(const T& val, typename std::enable_if<std::is_assignable<fn,T>::value>::type* = 0)
147 any(const T& val, typename std::enable_if<std::is_assignable<fn,T>::value>::type* = 0)
@@ -161,33 +151,33 @@ class any {
161 // any(T&& val, typename std::enable_if<std::is_assignable<fn,T>::value>::type* = 0)
151 // any(T&& val, typename std::enable_if<std::is_assignable<fn,T>::value>::type* = 0)
162 // : type(Type::Function), f(std::move(val)) {}
152 // : type(Type::Function), f(std::move(val)) {}
163
153
164− any(const shared_eff_fn& val) : type(Type::EffFunction), e(val) {}
154+ any(const shared<eff_fn>& val) : type(Type::EffFunction), e(val) {}
165− any(shared_eff_fn&& val) : type(Type::EffFunction), e(std::move(val)) {}
155+ any(shared<eff_fn>&& val) : type(Type::EffFunction), e(std::move(val)) {}
166
156
167 template <typename T>
157 template <typename T>
168 any(const T& val, typename std::enable_if<std::is_assignable<eff_fn,T>::value>::type* = 0)
158 any(const T& val, typename std::enable_if<std::is_assignable<eff_fn,T>::value>::type* = 0)
169 : type(Type::EffFunction), e(make_shared<eff_fn>(val)) {}
159 : type(Type::EffFunction), e(make_shared<eff_fn>(val)) {}
170
160
171− any(const shared_thunk& val) : type(Type::Thunk), t(val) {}
161+ any(const shared<thunk>& val) : type(Type::Thunk), t(val) {}
172− any(shared_thunk&& val) : type(Type::Thunk), t(std::move(val)) {}
162+ any(shared<thunk>&& val) : type(Type::Thunk), t(std::move(val)) {}
173
163
174 template <typename T>
164 template <typename T>
175 any(const T& val, typename std::enable_if<std::is_assignable<thunk,T>::value>::type* = 0)
165 any(const T& val, typename std::enable_if<std::is_assignable<thunk,T>::value>::type* = 0)
176 : type(Type::Thunk), t(make_shared<thunk>(val)) {}
166 : type(Type::Thunk), t(make_shared<thunk>(val)) {}
177
167
178 template <typename T>
168 template <typename T>
179− any(const T& val, typename std::enable_if<std::is_assignable<shared_void_ptr,T>::value>::type* = 0)
169+ any(const T& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0)
180 : type(Type::Pointer), p(val) {}
170 : type(Type::Pointer), p(val) {}
181
171
182 any(std::nullptr_t) : type(Type::Pointer), p(nullptr) {}
172 any(std::nullptr_t) : type(Type::Pointer), p(nullptr) {}
183
173
184 template <typename T>
174 template <typename T>
185− any(T&& val, typename std::enable_if<std::is_assignable<shared_void_ptr,T>::value>::type* = 0)
175+ any(T&& val, typename std::enable_if<std::is_assignable<shared<void>,T>::value>::type* = 0)
186 : type(Type::Pointer), p(std::move(val)) {}
176 : type(Type::Pointer), p(std::move(val)) {}
187
177
188 any(const any&);
178 any(const any&);
189
179
190− void swap(any&&);
180+ void swap(any&&) const;
191
181
192 any(any&& val) {
182 any(any&& val) {
193 swap(std::move(val));
183 swap(std::move(val));
@@ -226,7 +216,7 @@ class any {
226 auto cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type;
216 auto cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type;
227
217
228 template <typename T>
218 template <typename T>
229− auto cast() const -> typename std::enable_if<std::is_assignable<shared_void_ptr,T>::value, typename T::element_type*>::type {
219+ auto cast() const -> typename std::enable_if<std::is_assignable<shared<void>,T>::value, typename T::element_type*>::type {
230 if (type == Type::Pointer) {
220 if (type == Type::Pointer) {
231 return static_cast_shared<typename T::element_type>(p);
221 return static_cast_shared<typename T::element_type>(p);
232 }
222 }