git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: move operators out of classes; cleanup
53ecca2Andy Arvanitis
pcc/include/purescript.cc+247−387
@@ -16,7 +16,7 @@
16
16
17namespace PureScript {
17namespace PureScript {
18
18
19−#define copy_data(src) \
19+#define COPY_DATA(src) \
20 type = src.type; \
20 type = src.type; \
21 switch (type) { \
21 switch (type) { \
22 case Type::Integer: i = src.i; break; \
22 case Type::Integer: i = src.i; break; \
@@ -35,7 +35,7 @@ namespace PureScript {
35 default: assert(false && "Unsupported type in copy"); \
35 default: assert(false && "Unsupported type in copy"); \
36 }
36 }
37
37
38−#define move_data(src) \
38+#define MOVE_DATA(src) \
39 type = src.type; \
39 type = src.type; \
40 switch (type) { \
40 switch (type) { \
41 case Type::Integer: i = src.i; break; \
41 case Type::Integer: i = src.i; break; \
@@ -55,26 +55,26 @@ namespace PureScript {
55 }
55 }
56
56
57any::any(const any& other) {
57any::any(const any& other) {
58− copy_data(other);
58+ COPY_DATA(other);
59}
59}
60
60
61any::any(any&& other) noexcept {
61any::any(any&& other) noexcept {
62− move_data(other);
62+ MOVE_DATA(other);
63}
63}
64
64
65auto any::operator=(const any& rhs) -> any& {
65auto any::operator=(const any& rhs) -> any& {
66− copy_data(rhs);
66+ COPY_DATA(rhs);
67 return *this;
67 return *this;
68}
68}
69
69
70// Takes ownership -- might need to reconsider this
70// Takes ownership -- might need to reconsider this
71auto any::operator=(any& rhs) noexcept -> any& {
71auto any::operator=(any& rhs) noexcept -> any& {
72− move_data(rhs);
72+ MOVE_DATA(rhs);
73 return *this;
73 return *this;
74}
74}
75
75
76auto any::operator=(any&& rhs) noexcept -> any& {
76auto any::operator=(any&& rhs) noexcept -> any& {
77− move_data(rhs);
77+ MOVE_DATA(rhs);
78 return *this;
78 return *this;
79}
79}
80
80
@@ -98,467 +98,327 @@ any::~any() {
98 }
98 }
99};
99};
100
100
101− #define RETURN_VALUE(TYPE, VAL, FN) \
101+#define RETURN_VALUE(TYPE, VAL, FN) \
102+ if (type == TYPE) { \
103+ return FN(VAL); \
104+ } \
105+ const any* valuePtr = this; \
106+ do { \
107+ assert(valuePtr->type == Type::Thunk); \
108+ const any& value = (*valuePtr->t)(unthunk); \
102− if (type == TYPE) { \
109+ if (value.type == TYPE) { \
103− return FN(VAL); \
110+ return FN(value.VAL); \
104 } \
111 } \
105− const any* valuePtr = this; \
112+ valuePtr = &value; \
106− do { \
107− assert(valuePtr->type == Type::Thunk); \
108− const any& value = (*valuePtr->t)(unthunk); \
109− if (value.type == TYPE) { \
110− return FN(value.VAL); \
111− } \
112− valuePtr = &value; \
113− } while (valuePtr->type != Type::Unknown); \
113+ } while (valuePtr->type != Type::Unknown); \
114− assert(false && "Unknown value type"); \
114+ assert(false && "Unknown value type"); \
115− return FN(VAL);
115+ return FN(VAL);
116−
116+
117− template <typename T>
117+template <typename T>
118− auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
118+auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
119− RETURN_VALUE(Type::Integer, i,)
119+ RETURN_VALUE(Type::Integer, i,)
120− }
120+}
121− template auto any::cast<long>() const -> long;
121+template auto any::cast<long>() const -> long;
122
122
123− template <typename T>
123+template <typename T>
124− auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
124+auto any::cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type {
125− RETURN_VALUE(Type::Double, d,)
125+ RETURN_VALUE(Type::Double, d,)
126− }
126+}
127− template auto any::cast<double>() const -> double;
127+template auto any::cast<double>() const -> double;
128
128
129− template <typename T>
129+template <typename T>
130− auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
130+auto any::cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type {
131− RETURN_VALUE(Type::Character, c,)
131+ RETURN_VALUE(Type::Character, c,)
132− }
132+}
133− template auto any::cast<char>() const -> char;
133+template auto any::cast<char>() const -> char;
134
134
135− template <typename T>
135+template <typename T>
136− auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
136+auto any::cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type {
137− RETURN_VALUE(Type::Boolean, b,)
137+ RETURN_VALUE(Type::Boolean, b,)
138− }
138+}
139− template auto any::cast<bool>() const -> bool;
139+template auto any::cast<bool>() const -> bool;
140
140
141− template <typename T>
141+template <typename T>
142− auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
142+auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, const T&>::type {
143− RETURN_VALUE(Type::String, s, *)
143+ RETURN_VALUE(Type::String, s, *)
144− }
144+}
145− template auto any::cast<string>() const -> const string&;
145+template auto any::cast<string>() const -> const string&;
146
146
147− template <typename T>
147+template <typename T>
148− auto any::cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type {
148+auto any::cast() const -> typename std::enable_if<std::is_same<T, const char*>::value, const T>::type {
149− RETURN_VALUE(Type::String, s->c_str(),)
149+ RETURN_VALUE(Type::String, s->c_str(),)
150− }
150+}
151− template auto any::cast<const char*>() const -> const char* const;
151+template auto any::cast<const char*>() const -> const char* const;
152
152
153− template <typename T>
153+template <typename T>
154− auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
154+auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type {
155− RETURN_VALUE(Type::Map, m, *)
155+ RETURN_VALUE(Type::Map, m, *)
156− }
156+}
157− template auto any::cast<any::map>() const -> const map&;
157+template auto any::cast<any::map>() const -> const map&;
158
158
159− template <typename T>
159+template <typename T>
160− auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
160+auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
161− RETURN_VALUE(Type::Vector, v, *)
161+ RETURN_VALUE(Type::Vector, v, *)
162− }
162+}
163− template auto any::cast<any::vector>() const -> const vector&;
163+template auto any::cast<any::vector>() const -> const vector&;
164
164
165− auto any::operator()(const any& arg) const -> any {
165+auto any::operator()(const any& arg) const -> any {
166− if (type == Type::Function) {
166+ if (type == Type::Function) {
167− return (*f)(arg);
168− }
169− if (type == Type::Closure) {
170− return (*l)(arg);
167+ return (*f)(arg);
171− }
172− const any* valuePtr = this;
173− do {
174− assert(valuePtr->type == Type::Thunk);
175− const any& value = (*valuePtr->t)(unthunk);
176− if (value.type == Type::Function) {
177− return (*value.f)(arg);
178− }
179− if (value.type == Type::Closure) {
180− return (*value.l)(arg);
181− }
182− valuePtr = &value;
183− } while (valuePtr->type != Type::Unknown);
184− assert(false && "Unknown value type");
185− return nullptr;
186 }
168 }
187−
188− auto any::operator()(const as_thunk) const -> const any& {
189− assert(type == Type::Thunk);
169+ if (type == Type::Closure) {
190− return (*t)(unthunk);
170+ return (*l)(arg);
191 }
171 }
192−
172+ const any* valuePtr = this;
193− auto any::operator()() const -> any {
173+ do {
174+ assert(valuePtr->type == Type::Thunk);
175+ const any& value = (*valuePtr->t)(unthunk);
194− if (type == Type::EffFunction) {
176+ if (value.type == Type::Function) {
195− return (*e)();
177+ return (*value.f)(arg);
196 }
178 }
197− const any* valuePtr = this;
198− do {
199− assert(valuePtr->type == Type::Thunk);
200− const any& value = (*valuePtr->t)(unthunk);
201− if (value.type == Type::EffFunction) {
179+ if (value.type == Type::Closure) {
202− return (*value.e)();
180+ return (*value.l)(arg);
203− }
204− valuePtr = &value;
205− } while (valuePtr->type != Type::Unknown);
206− assert(false && "Unknown value type");
207− return nullptr;
208− }
209−
210− any::operator long() const {
211− RETURN_VALUE(Type::Integer, i,)
212− }
213−
214− any::operator double() const {
215− RETURN_VALUE(Type::Double, d,)
216− }
217−
218− any::operator bool() const {
219− RETURN_VALUE(Type::Boolean, b,)
220− }
221−
222− any::operator const string&() const {
223− RETURN_VALUE(Type::String, s, *)
224− }
225−
226− any::operator const map&() const {
227− RETURN_VALUE(Type::Map, m, *)
228− }
229−
230− any::operator const vector&() const {
231− RETURN_VALUE(Type::Vector, v, *)
232− }
233−
234− auto any::extractPointer() const -> void* {
235− RETURN_VALUE(Type::Pointer, p.get(),)
236− }
237−
238− auto any::extract_value(const any& a) -> const any& {
239− if (a.type != Type::Thunk) {
240− return a;
241 }
181 }
242− const any* valuePtr = &a;
182+ valuePtr = &value;
243− do {
244− const any& value = (*valuePtr->t)(unthunk);
245− if (value.type != Type::Thunk) {
246− return value;
247− }
248− valuePtr = &value;
249− } while (valuePtr->type != Type::Unknown);
183+ } while (valuePtr->type != Type::Unknown);
250− assert(false && "Unknown value type");
184+ assert(false && "Unknown value type");
251− return a;
185+ return nullptr;
252− }
186+}
253
187
254− auto any::operator[](const map_key_t& rhs) const -> const any& {
188+auto any::operator()(const as_thunk) const -> const any& {
255− RETURN_VALUE(Type::Map, m->at(rhs),)
189+ assert(type == Type::Thunk);
190+ return (*t)(unthunk);
256− }
191+}
257
192
258− auto any::operator[](const vector::size_type rhs) const -> const any& {
193+auto any::operator()() const -> any {
259− RETURN_VALUE(Type::Vector, v->at(rhs),)
194+ if (type == Type::EffFunction) {
195+ return (*e)();
260 }
196 }
197+ const any* valuePtr = this;
198+ do {
199+ assert(valuePtr->type == Type::Thunk);
200+ const any& value = (*valuePtr->t)(unthunk);
201+ if (value.type == Type::EffFunction) {
202+ return (*value.e)();
203+ }
204+ valuePtr = &value;
205+ } while (valuePtr->type != Type::Unknown);
206+ assert(false && "Unknown value type");
207+ return nullptr;
208+}
261
209
262− auto any::operator[](const any& rhs) const -> const any& {
210+any::operator long() const {
263− RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
211+ RETURN_VALUE(Type::Integer, i,)
264− }
212+}
265
213
266−#define DEFINE_OPERATOR_LHS(K, T, OP, V, R, P) \
214+any::operator double() const {
267−auto operator OP(const T lhs, const any& rhs_) -> R { \
215+ RETURN_VALUE(Type::Double, d,)
268− const any& rhs = any::extract_value(rhs_); \
269− assert(rhs.type == any::Type::K); \
270− return lhs OP P(rhs.V); \
271}
216}
272
217
273−#define DEFINE_OPERATOR_RHS(K, T, OP, V, R, P) \
274−auto any::operator OP(const T rhs) const -> R { \
218+any::operator bool() const {
275− const any& lhs = any::extract_value(*this); \
219+ RETURN_VALUE(Type::Boolean, b,)
276− assert(lhs.type == Type::K); \
277− return P(lhs.V) OP rhs; \
278}
220}
279
221
280−auto any::operator==(const any& rhs_) const -> bool {
222+any::operator const string&() const {
281− const any& lhs = extract_value(*this);
282− const any& rhs = extract_value(rhs_);
283− assert(lhs.type == rhs.type);
284− switch (lhs.type) {
285− case Type::Integer: return lhs.i == rhs.i;
286− case Type::Double: return lhs.d == rhs.d;
287− case Type::Character: return lhs.c == rhs.c;
288− case Type::Boolean: return lhs.b == rhs.b;
289− case Type::String: return (*lhs.s) == (*rhs.s);
223+ RETURN_VALUE(Type::String, s, *)
290− case Type::Pointer: return lhs.p == rhs.p;
291− default: assert(false && "Unsupported type for '==' operator");
292− }
293− return false;
294}
224}
295
225
296−DEFINE_OPERATOR_RHS(Integer, long, ==, i, bool,)
226+any::operator const map&() const {
297−DEFINE_OPERATOR_RHS(Double, double, ==, d, bool,)
227+ RETURN_VALUE(Type::Map, m, *)
298−DEFINE_OPERATOR_RHS(Character, char, ==, c, bool,)
228+}
299−DEFINE_OPERATOR_RHS(Boolean, bool, ==, b, bool,)
300−DEFINE_OPERATOR_RHS(String, string&, ==, s, bool, *)
301−DEFINE_OPERATOR_RHS(String, char* const, ==, s, bool, *)
302
229
303−auto any::operator!=(const any& rhs_) const -> bool {
230+any::operator const vector&() const {
304− const any& lhs = extract_value(*this);
231+ RETURN_VALUE(Type::Vector, v, *)
305− const any& rhs = extract_value(rhs_);
306− assert(lhs.type == rhs.type);
307− switch (lhs.type) {
308− case Type::Integer: return lhs.i != rhs.i;
309− case Type::Double: return lhs.d != rhs.d;
310− case Type::Character: return lhs.c != rhs.c;
311− case Type::Boolean: return lhs.b != rhs.b;
312− case Type::String: return (*lhs.s) != (*rhs.s);
313− case Type::Pointer: return lhs.p != rhs.p;
314− default: assert(false && "Unsupported type for '!=' operator");
315− }
316− return false;
317}
232}
318
233
319−DEFINE_OPERATOR_RHS(Integer, long, !=, i, bool,)
234+auto any::extractPointer() const -> void* {
320−DEFINE_OPERATOR_RHS(Double, double, !=, d, bool,)
235+ RETURN_VALUE(Type::Pointer, p.get(),)
321−DEFINE_OPERATOR_RHS(Character, char, !=, c, bool,)
236+}
322−DEFINE_OPERATOR_RHS(Boolean, bool, !=, b, bool,)
323−DEFINE_OPERATOR_RHS(String, string&, !=, s, bool, *)
324−DEFINE_OPERATOR_RHS(String, char* const, !=, s, bool, *)
325
237
326−auto any::operator<(const any& rhs_) const -> bool {
238+auto any::extractValue(const any& a) -> const any& {
327− const any& lhs = extract_value(*this);
239+ if (a.type != Type::Thunk) {
328− const any& rhs = extract_value(rhs_);
240+ return a;
329− assert(lhs.type == rhs.type);
330− switch (lhs.type) {
331− case Type::Integer: return lhs.i < rhs.i;
332− case Type::Double: return lhs.d < rhs.d;
333− case Type::Character: return lhs.c < rhs.c;
334− case Type::Boolean: return lhs.b < rhs.b;
335− case Type::String: return (*lhs.s) < (*rhs.s);
336− default: assert(false && "Unsupported type for '<' operator");
337 }
241 }
242+ const any* valuePtr = &a;
243+ do {
244+ const any& value = (*valuePtr->t)(unthunk);
245+ if (value.type != Type::Thunk) {
338− return false;
246+ return value;
247+ }
248+ valuePtr = &value;
249+ } while (valuePtr->type != Type::Unknown);
250+ assert(false && "Unknown value type");
251+ return a;
339}
252}
340
253
341−DEFINE_OPERATOR_RHS(Integer, long, <, i, bool,)
342−DEFINE_OPERATOR_RHS(Double, double, <, d, bool,)
343−DEFINE_OPERATOR_RHS(Character, char, <, c, bool,)
344−DEFINE_OPERATOR_RHS(Boolean, bool, <, b, bool,)
345−DEFINE_OPERATOR_RHS(String, string&, <, s, bool, *)
346−DEFINE_OPERATOR_RHS(String, char* const, <, s, bool, *)
347−
348−auto any::operator<=(const any& rhs_) const -> bool {
254+auto any::operator[](const map_key_t& rhs) const -> const any& {
349− const any& lhs = extract_value(*this);
255+ RETURN_VALUE(Type::Map, m->at(rhs),)
350− const any& rhs = extract_value(rhs_);
351− assert(lhs.type == rhs.type);
352− switch (lhs.type) {
353− case Type::Integer: return lhs.i <= rhs.i;
354− case Type::Double: return lhs.d <= rhs.d;
355− case Type::Character: return lhs.c <= rhs.c;
356− case Type::Boolean: return lhs.b <= rhs.b;
357− case Type::String: return (*lhs.s) <= (*rhs.s);
358− default: assert(false && "Unsupported type for '<' operator");
359− }
360− return false;
361}
256}
362
257
363−DEFINE_OPERATOR_RHS(Integer, long, <=, i, bool,)
258+auto any::operator[](const vector::size_type rhs) const -> const any& {
364−DEFINE_OPERATOR_RHS(Double, double, <=, d, bool,)
259+ RETURN_VALUE(Type::Vector, v->at(rhs),)
365−DEFINE_OPERATOR_RHS(Character, char, <=, c, bool,)
260+}
366−DEFINE_OPERATOR_RHS(Boolean, bool, <=, b, bool,)
367−DEFINE_OPERATOR_RHS(String, string&, <=, s, bool, *)
368−DEFINE_OPERATOR_RHS(String, char* const, <=, s, bool, *)
369
261
370−auto any::operator>(const any& rhs_) const -> bool {
262+auto any::operator[](const any& rhs) const -> const any& {
371− const any& lhs = extract_value(*this);
263+ RETURN_VALUE(Type::Vector, v->at(rhs.cast<long>()),)
372− const any& rhs = extract_value(rhs_);
373− assert(lhs.type == rhs.type);
374− switch (lhs.type) {
375− case Type::Integer: return lhs.i > rhs.i;
376− case Type::Double: return lhs.d > rhs.d;
377− case Type::Character: return lhs.c > rhs.c;
378− case Type::Boolean: return lhs.b > rhs.b;
379− case Type::String: return (*lhs.s) > (*rhs.s);
380− default: assert(false && "Unsupported type for '>' operator");
381− }
382− return false;
383}
264}
384
265
385−DEFINE_OPERATOR_RHS(Integer, long, >, i, bool,)
266+//-----------------------------------------------------------------------------
386−DEFINE_OPERATOR_RHS(Double, double, >, d, bool,)
267+// Operator helper macros
387−DEFINE_OPERATOR_RHS(Character, char, >, c, bool,)
268+//-----------------------------------------------------------------------------
388−DEFINE_OPERATOR_RHS(Boolean, bool, >, b, bool,)
389−DEFINE_OPERATOR_RHS(String, string&, >, s, bool, *)
390−DEFINE_OPERATOR_RHS(String, char* const, >, s, bool, *)
391
269
392−auto any::operator>=(const any& rhs_) const -> bool {
270+#define DEFINE_OPERATOR(op, ty, rty) \
393− const any& lhs = extract_value(*this);
271+auto operator op (const any& lhs, ty rhs) -> rty { \
394− const any& rhs = extract_value(rhs_);
272+ return lhs.cast<typename std::remove_const<std::remove_reference<ty>::type>::type>() op rhs; \
395− assert(lhs.type == rhs.type);
396− switch (lhs.type) {
397− case Type::Integer: return lhs.i >= rhs.i;
398− case Type::Double: return lhs.d >= rhs.d;
399− case Type::Character: return lhs.c >= rhs.c;
400− case Type::Boolean: return lhs.b >= rhs.b;
401− case Type::String: return (*lhs.s) >= (*rhs.s);
402− default: assert(false && "Unsupported type for '>' operator");
403− }
273+} \
404− return false;
274+auto operator op (ty lhs, const any& rhs) -> rty { \
275+ return lhs op rhs.cast<typename std::remove_const<std::remove_reference<ty>::type>::type>(); \
405}
276}
406
277
407−DEFINE_OPERATOR_RHS(Integer, long, >=, i, bool,)
278+#define DEFINE_CSTR_COMPARISON_OPERATOR(op) \
408−DEFINE_OPERATOR_RHS(Double, double, >=, d, bool,)
279+ auto operator op (const any& lhs, const char * rhs) -> bool { \
409−DEFINE_OPERATOR_RHS(Character, char, >=, c, bool,)
280+ return lhs.cast<string>() op rhs; \
410−DEFINE_OPERATOR_RHS(Boolean, bool, >=, b, bool,)
281+ } \
411−DEFINE_OPERATOR_RHS(String, string&, >=, s, bool, *)
282+ auto operator op (const char * lhs, const any& rhs) -> bool { \
412−DEFINE_OPERATOR_RHS(String, char* const, >=, s, bool, *)
283+ return lhs op rhs.cast<string>(); \
413−
284+ }
285+
286+#define DEFINE_COMPARISON_OPERATOR(op) \
287+ auto operator op (const any& lhs_, const any& rhs_) -> bool { \
288+ const any& lhs = any::extractValue(lhs_); \
289+ const any& rhs = any::extractValue(rhs_); \
290+ assert(lhs.type == rhs.type); \
291+ switch (lhs.type) { \
292+ case any::Type::Integer: return lhs.i op rhs.i; \
293+ case any::Type::Double: return lhs.d op rhs.d; \
294+ case any::Type::Character: return lhs.c op rhs.c; \
295+ case any::Type::Boolean: return lhs.b op rhs.b; \
296+ case any::Type::String: return (*lhs.s) op (*rhs.s); \
297+ case any::Type::Pointer: return lhs.p op rhs.p; \
298+ default: assert(false && "Unsupported type for operator " #op); \
299+ } \
300+ return false; \
301+ } \
302+ DEFINE_OPERATOR(op, long, bool) \
303+ DEFINE_OPERATOR(op, double, bool) \
304+ DEFINE_OPERATOR(op, char, bool) \
305+ DEFINE_OPERATOR(op, bool, bool) \
306+ DEFINE_OPERATOR(op, const string&, bool) \
307+ DEFINE_CSTR_COMPARISON_OPERATOR(op)
308+
309+//-----------------------------------------------------------------------------
310+// Operator definitions
311+//-----------------------------------------------------------------------------
312+
313+DEFINE_COMPARISON_OPERATOR(==)
314+DEFINE_COMPARISON_OPERATOR(!=)
315+DEFINE_COMPARISON_OPERATOR(<)
316+DEFINE_COMPARISON_OPERATOR(<=)
317+DEFINE_COMPARISON_OPERATOR(>)
318+DEFINE_COMPARISON_OPERATOR(>=)
319+
414−auto any::operator+(const any& rhs_) const -> any {
320+auto operator+(const any& lhs_, const any& rhs_) -> any {
415− const any& lhs = extract_value(*this);
321+ const any& lhs = any::extractValue(lhs_);
416− const any& rhs = extract_value(rhs_);
322+ const any& rhs = any::extractValue(rhs_);
417 assert(lhs.type == rhs.type);
323 assert(lhs.type == rhs.type);
418 switch (lhs.type) {
324 switch (lhs.type) {
419− case Type::Integer: return lhs.i + rhs.i;
325+ case any::Type::Integer: return lhs.i + rhs.i;
420− case Type::Double: return lhs.d + rhs.d;
326+ case any::Type::Double: return lhs.d + rhs.d;
421− case Type::Character: return any(char(lhs.c + rhs.c));
327+ case any::Type::Character: return any(char(lhs.c + rhs.c));
422− case Type::String: return (*lhs.s) + (*rhs.s);
328+ case any::Type::String: return (*lhs.s) + (*rhs.s);
423 default: assert(false && "Unsupported type for '+' operator");
329 default: assert(false && "Unsupported type for '+' operator");
424 }
330 }
425 return nullptr;
331 return nullptr;
426}
332}
427
333
428−DEFINE_OPERATOR_RHS(Integer, long, +, i, long,)
334+DEFINE_OPERATOR(+, long, long)
429−DEFINE_OPERATOR_RHS(Double, double, +, d, double,)
335+DEFINE_OPERATOR(+, double, double)
430−DEFINE_OPERATOR_RHS(Character, char, +, c, char,)
336+DEFINE_OPERATOR(+, char, char)
431−DEFINE_OPERATOR_RHS(String, string&, +, s, string, *)
337+DEFINE_OPERATOR(+, const string&, string)
432−DEFINE_OPERATOR_RHS(String, char* const, +, s, string, *)
433
338
339+auto operator+(const any& lhs, const char * rhs) -> string {
340+ return lhs.cast<string>() + rhs;
341+}
342+
343+auto operator+(const char * lhs, const any& rhs) -> string {
344+ return lhs + rhs.cast<string>();
345+}
346+
434−auto any::operator-(const any& rhs_) const -> any {
347+auto operator-(const any& lhs_, const any& rhs_) -> any {
435− const any& lhs = extract_value(*this);
348+ const any& lhs = any::extractValue(lhs_);
436− const any& rhs = extract_value(rhs_);
349+ const any& rhs = any::extractValue(rhs_);
437 assert(lhs.type == rhs.type);
350 assert(lhs.type == rhs.type);
438 switch (lhs.type) {
351 switch (lhs.type) {
439− case Type::Integer: return lhs.i - rhs.i;
352+ case any::Type::Integer: return lhs.i - rhs.i;
440− case Type::Double: return lhs.d - rhs.d;
353+ case any::Type::Double: return lhs.d - rhs.d;
441− case Type::Character: return any(char(lhs.c - rhs.c));
354+ case any::Type::Character: return any(char(lhs.c - rhs.c));
442− default: assert(false && "Unsupported type for '-' binary operator");
355+ default: assert(false && "Unsupported type for '-' operator");
443 }
356 }
444 return nullptr;
357 return nullptr;
445}
358}
446
359
447−DEFINE_OPERATOR_RHS(Integer, long, -, i, long,)
360+DEFINE_OPERATOR(-, long, long)
448−DEFINE_OPERATOR_RHS(Double, double, -, d, double,)
361+DEFINE_OPERATOR(-, double, double)
449−DEFINE_OPERATOR_RHS(Character, char, -, c, char,)
362+DEFINE_OPERATOR(-, char, char)
450
363
451−auto any::operator*(const any& rhs_) const -> any {
364+auto operator*(const any& lhs_, const any& rhs_) -> any {
452− const any& lhs = extract_value(*this);
365+ const any& lhs = any::extractValue(lhs_);
453− const any& rhs = extract_value(rhs_);
366+ const any& rhs = any::extractValue(rhs_);
454 assert(lhs.type == rhs.type);
367 assert(lhs.type == rhs.type);
455 switch (lhs.type) {
368 switch (lhs.type) {
456− case Type::Integer: return lhs.i * rhs.i;
369+ case any::Type::Integer: return lhs.i * rhs.i;
457− case Type::Double: return lhs.d * rhs.d;
370+ case any::Type::Double: return lhs.d * rhs.d;
371+ case any::Type::Character: return any(char(lhs.c * rhs.c));
458 default: assert(false && "Unsupported type for '*' operator");
372 default: assert(false && "Unsupported type for '*' operator");
459 }
373 }
460 return nullptr;
374 return nullptr;
461}
375}
462
376
463−DEFINE_OPERATOR_RHS(Integer, long, *, i, long,)
377+DEFINE_OPERATOR(*, long, long)
464−DEFINE_OPERATOR_RHS(Double, double, *, d, double,)
378+DEFINE_OPERATOR(*, double, double)
379+DEFINE_OPERATOR(*, char, char)
465
380
466−auto any::operator/(const any& rhs_) const -> any {
381+auto operator/(const any& lhs_, const any& rhs_) -> any {
467− const any& lhs = extract_value(*this);
382+ const any& lhs = any::extractValue(lhs_);
468− const any& rhs = extract_value(rhs_);
383+ const any& rhs = any::extractValue(rhs_);
469 assert(lhs.type == rhs.type);
384 assert(lhs.type == rhs.type);
470 switch (lhs.type) {
385 switch (lhs.type) {
471− case Type::Integer: return lhs.i / rhs.i;
386+ case any::Type::Integer: return lhs.i / rhs.i;
472− case Type::Double: return lhs.d / rhs.d;
387+ case any::Type::Double: return lhs.d / rhs.d;
388+ case any::Type::Character: return any(char(lhs.c / rhs.c));
473 default: assert(false && "Unsupported type for '/' operator");
389 default: assert(false && "Unsupported type for '/' operator");
474 }
390 }
475 return nullptr;
391 return nullptr;
476}
392}
477
393
478−DEFINE_OPERATOR_RHS(Integer, long, /, i, long,)
394+DEFINE_OPERATOR(/, long, long)
479−DEFINE_OPERATOR_RHS(Double, double, /, d, double,)
395+DEFINE_OPERATOR(/, double, double)
396+DEFINE_OPERATOR(/, char, char)
480
397
481−auto any::operator%(const any& rhs_) const -> any {
398+auto operator%(const any& lhs_, const any& rhs_) -> any {
482− const any& lhs = extract_value(*this);
399+ const any& lhs = any::extractValue(lhs_);
483− const any& rhs = extract_value(rhs_);
400+ const any& rhs = any::extractValue(rhs_);
484 assert(lhs.type == rhs.type);
401 assert(lhs.type == rhs.type);
485 switch (lhs.type) {
402 switch (lhs.type) {
486− case Type::Integer: return lhs.i % rhs.i;
403+ case any::Type::Integer: return lhs.i % rhs.i;
404+ case any::Type::Character: return any(char(lhs.c % rhs.c));
487 default: assert(false && "Unsupported type for '%' operator");
405 default: assert(false && "Unsupported type for '%' operator");
488 }
406 }
489 return nullptr;
407 return nullptr;
490}
408}
491
409
492−DEFINE_OPERATOR_RHS(Integer, long, %, i, long,)
410+DEFINE_OPERATOR(%, long, long)
411+DEFINE_OPERATOR(%, char, char)
493
412
413+// unary negate
494−auto any::operator-() const -> any {
414+auto operator-(const any& rhs_) -> any {
495− const any& lhs = any::extract_value(*this);
415+ const any& rhs = any::extractValue(rhs_);
496− switch (lhs.type) {
416+ switch (rhs.type) {
497− case Type::Integer: return (- lhs.i);
417+ case any::Type::Integer: return (- rhs.i);
498− case Type::Double: return (- lhs.d);
418+ case any::Type::Double: return (- rhs.d);
499 default: assert(false && "Unsupported type for unary '-' operator");
419 default: assert(false && "Unsupported type for unary '-' operator");
500 }
420 }
501 return nullptr;
421 return nullptr;
502}
422}
503
423
504−DEFINE_OPERATOR_LHS(Integer, long, ==, i, bool,)
505−DEFINE_OPERATOR_LHS(Integer, long, !=, i, bool,)
506−DEFINE_OPERATOR_LHS(Integer, long, <, i, bool,)
507−DEFINE_OPERATOR_LHS(Integer, long, <=, i, bool,)
508−DEFINE_OPERATOR_LHS(Integer, long, >, i, bool,)
509−DEFINE_OPERATOR_LHS(Integer, long, >=, i, bool,)
510−
511−DEFINE_OPERATOR_LHS(Double, double, ==, d, bool,)
512−DEFINE_OPERATOR_LHS(Double, double, !=, d, bool,)
513−DEFINE_OPERATOR_LHS(Double, double, <, d, bool,)
514−DEFINE_OPERATOR_LHS(Double, double, <=, d, bool,)
515−DEFINE_OPERATOR_LHS(Double, double, >, d, bool,)
516−DEFINE_OPERATOR_LHS(Double, double, >=, d, bool,)
517−
518−DEFINE_OPERATOR_LHS(Character, char, ==, c, bool,)
519−DEFINE_OPERATOR_LHS(Character, char, !=, c, bool,)
520−DEFINE_OPERATOR_LHS(Character, char, <, c, bool,)
521−DEFINE_OPERATOR_LHS(Character, char, <=, c, bool,)
522−DEFINE_OPERATOR_LHS(Character, char, >, c, bool,)
523−DEFINE_OPERATOR_LHS(Character, char, >=, c, bool,)
524−
525−DEFINE_OPERATOR_LHS(Boolean, bool, ==, b, bool,)
526−DEFINE_OPERATOR_LHS(Boolean, bool, !=, b, bool,)
527−DEFINE_OPERATOR_LHS(Boolean, bool, <, b, bool,)
528−DEFINE_OPERATOR_LHS(Boolean, bool, <=, b, bool,)
529−DEFINE_OPERATOR_LHS(Boolean, bool, >, b, bool,)
530−DEFINE_OPERATOR_LHS(Boolean, bool, >=, b, bool,)
531−
532−DEFINE_OPERATOR_LHS(String, string&, ==, s, bool, *)
533−DEFINE_OPERATOR_LHS(String, string&, !=, s, bool, *)
534−DEFINE_OPERATOR_LHS(String, string&, <, s, bool, *)
535−DEFINE_OPERATOR_LHS(String, string&, <=, s, bool, *)
536−DEFINE_OPERATOR_LHS(String, string&, >, s, bool, *)
537−DEFINE_OPERATOR_LHS(String, string&, >=, s, bool, *)
538−
539−DEFINE_OPERATOR_LHS(String, char* const, ==, s, bool, *)
540−DEFINE_OPERATOR_LHS(String, char* const, !=, s, bool, *)
541−DEFINE_OPERATOR_LHS(String, char* const, <, s, bool, *)
542−DEFINE_OPERATOR_LHS(String, char* const, <=, s, bool, *)
543−DEFINE_OPERATOR_LHS(String, char* const, >, s, bool, *)
544−DEFINE_OPERATOR_LHS(String, char* const, >=, s, bool, *)
545−
546−DEFINE_OPERATOR_LHS(Integer, long, +, i, long,)
547−DEFINE_OPERATOR_LHS(Integer, long, -, i, long,)
548−DEFINE_OPERATOR_LHS(Integer, long, *, i, long,)
549−DEFINE_OPERATOR_LHS(Integer, long, /, i, long,)
550−DEFINE_OPERATOR_LHS(Integer, long, %, i, long,)
551−
552−DEFINE_OPERATOR_LHS(Double, double, +, d, double,)
553−DEFINE_OPERATOR_LHS(Double, double, -, d, double,)
554−DEFINE_OPERATOR_LHS(Double, double, *, d, double,)
555−DEFINE_OPERATOR_LHS(Double, double, /, d, double,)
556−
557−DEFINE_OPERATOR_LHS(Character, char, +, i, char,)
558−DEFINE_OPERATOR_LHS(Character, char, -, i, char,)
559−
560−DEFINE_OPERATOR_LHS(String, string&, +, s, string, *)
561−DEFINE_OPERATOR_LHS(String, char* const, +, s, string, *)
562−
563−
564} // namespace PureScript
424} // namespace PureScript
pcc/include/purescript.hh+55−133
@@ -33,6 +33,18 @@
33#include <stdexcept>
33#include <stdexcept>
34#include "map_key.hh"
34#include "map_key.hh"
35
35
36+#define DECLARE_OPERATOR(op, ty, rty) \
37+ friend auto operator op (const any&, ty) -> rty; \
38+ friend auto operator op (ty, const any&) -> rty;
39+
40+#define DECLARE_COMPARISON_OPERATOR(op) \
41+ friend auto operator op (const any&, const any&) -> bool; \
42+ DECLARE_OPERATOR(op, long, bool) \
43+ DECLARE_OPERATOR(op, double, bool) \
44+ DECLARE_OPERATOR(op, char, bool) \
45+ DECLARE_OPERATOR(op, const string&, bool) \
46+ DECLARE_OPERATOR(op, const char *, bool)
47+
36namespace PureScript {
48namespace PureScript {
37
49
38using string = std::string;
50using string = std::string;
@@ -206,142 +218,52 @@ class any {
206
218
207 auto extractPointer() const -> void*;
219 auto extractPointer() const -> void*;
208
220
209− static auto extract_value(const any&) -> const any&;
221+ static auto extractValue(const any&) -> const any&;
210−
222+
211− auto operator==(const any&) const -> bool;
223+ DECLARE_COMPARISON_OPERATOR(==)
212− auto operator==(const long) const -> bool;
224+ DECLARE_COMPARISON_OPERATOR(!=)
213− auto operator==(const double) const -> bool;
225+ DECLARE_COMPARISON_OPERATOR(<)
214− auto operator==(const char) const -> bool;
226+ DECLARE_COMPARISON_OPERATOR(<=)
215− auto operator==(const bool) const -> bool;
227+ DECLARE_COMPARISON_OPERATOR(>)
216− auto operator==(const string&) const -> bool;
228+ DECLARE_COMPARISON_OPERATOR(>=)
217− auto operator==(const char * const) const -> bool;
229+
218−
219− auto operator!=(const any&) const -> bool;
220− auto operator!=(const long) const -> bool;
221− auto operator!=(const double) const -> bool;
222− auto operator!=(const char) const -> bool;
223− auto operator!=(const bool) const -> bool;
224− auto operator!=(const string&) const -> bool;
225− auto operator!=(const char * const) const -> bool;
226−
227− auto operator<(const any&) const -> bool;
228− auto operator<(const long) const -> bool;
229− auto operator<(const double) const -> bool;
230− auto operator<(const char) const -> bool;
231− auto operator<(const bool) const -> bool;
232− auto operator<(const string&) const -> bool;
233− auto operator<(const char * const) const -> bool;
234−
235− auto operator<=(const any&) const -> bool;
236− auto operator<=(const long) const -> bool;
237− auto operator<=(const double) const -> bool;
238− auto operator<=(const char) const -> bool;
239− auto operator<=(const bool) const -> bool;
240− auto operator<=(const string&) const -> bool;
241− auto operator<=(const char * const) const -> bool;
242−
243− auto operator>(const any&) const -> bool;
244− auto operator>(const long) const -> bool;
245− auto operator>(const double) const -> bool;
246− auto operator>(const char) const -> bool;
247− auto operator>(const bool) const -> bool;
248− auto operator>(const string&) const -> bool;
249− auto operator>(const char * const) const -> bool;
250−
251− auto operator>=(const any&) const -> bool;
252− auto operator>=(const long) const -> bool;
253− auto operator>=(const double) const -> bool;
254− auto operator>=(const char) const -> bool;
255− auto operator>=(const bool) const -> bool;
256− auto operator>=(const string&) const -> bool;
257− auto operator>=(const char * const) const -> bool;
258−
259− auto operator+(const any&) const -> any;
260− auto operator+(const long) const -> long;
261− auto operator+(const double) const -> double;
262− auto operator+(const char) const -> char;
263− auto operator+(const string&) const -> string;
264− auto operator+(const char * const) const -> string;
265−
266− auto operator-(const any&) const -> any;
267− auto operator-(const long) const -> long;
268− auto operator-(const double) const -> double;
269− auto operator-(const char) const -> char;
270−
271− auto operator*(const any&) const -> any;
272− auto operator*(const long) const -> long;
273− auto operator*(const double) const -> double;
274−
275− auto operator/(const any&) const -> any;
276− auto operator/(const long) const -> long;
277− auto operator/(const double) const -> double;
278−
279− auto operator%(const any&) const -> any;
280− auto operator%(const long) const -> long;
281−
282− auto operator-() const -> any; // unary negate
283−
284− friend auto operator==(const long, const any&) -> bool;
285− friend auto operator!=(const long, const any&) -> bool;
286− friend auto operator< (const long, const any&) -> bool;
287− friend auto operator<=(const long, const any&) -> bool;
288− friend auto operator> (const long, const any&) -> bool;
289− friend auto operator>=(const long, const any&) -> bool;
290−
291− friend auto operator==(const double, const any&) -> bool;
292− friend auto operator!=(const double, const any&) -> bool;
293− friend auto operator< (const double, const any&) -> bool;
294− friend auto operator<=(const double, const any&) -> bool;
295− friend auto operator> (const double, const any&) -> bool;
296− friend auto operator>=(const double, const any&) -> bool;
297−
298− friend auto operator==(const char, const any&) -> bool;
299− friend auto operator!=(const char, const any&) -> bool;
300− friend auto operator< (const char, const any&) -> bool;
301− friend auto operator<=(const char, const any&) -> bool;
302− friend auto operator> (const char, const any&) -> bool;
303− friend auto operator>=(const char, const any&) -> bool;
304−
305− friend auto operator==(const bool, const any&) -> bool;
306− friend auto operator!=(const bool, const any&) -> bool;
307− friend auto operator< (const bool, const any&) -> bool;
308− friend auto operator<=(const bool, const any&) -> bool;
309− friend auto operator> (const bool, const any&) -> bool;
310− friend auto operator>=(const bool, const any&) -> bool;
311−
312− friend auto operator==(const string&, const any&) -> bool;
313− friend auto operator!=(const string&, const any&) -> bool;
314− friend auto operator< (const string&, const any&) -> bool;
315− friend auto operator<=(const string&, const any&) -> bool;
316− friend auto operator> (const string&, const any&) -> bool;
317− friend auto operator>=(const string&, const any&) -> bool;
318−
319− friend auto operator==(const char* const, const any&) -> bool;
320− friend auto operator!=(const char* const, const any&) -> bool;
321− friend auto operator< (const char* const, const any&) -> bool;
322− friend auto operator<=(const char* const, const any&) -> bool;
323− friend auto operator> (const char* const, const any&) -> bool;
324− friend auto operator>=(const char* const, const any&) -> bool;
325−
326− friend auto operator+(const long, const any&) -> long;
230+ friend auto operator+(const any&, const any&) -> any;
327− friend auto operator-(const long, const any&) -> long;
231+
328− friend auto operator*(const long, const any&) -> long;
232+ DECLARE_OPERATOR(+, long, long)
329− friend auto operator/(const long, const any&) -> long;
233+ DECLARE_OPERATOR(+, double, double)
330− friend auto operator%(const long, const any&) -> long;
234+ DECLARE_OPERATOR(+, char, char)
331−
235+ DECLARE_OPERATOR(+, const string&, string)
332− friend auto operator+(const double, const any&) -> double;
236+ DECLARE_OPERATOR(+, const char *, string)
237+
333− friend auto operator-(const double, const any&) -> double;
238+ friend auto operator-(const any&, const any&) -> any;
334− friend auto operator*(const double, const any&) -> double;
239+
335− friend auto operator/(const double, const any&) -> double;
240+ DECLARE_OPERATOR(-, long, long)
336−
241+ DECLARE_OPERATOR(-, double, double)
337− friend auto operator+(const char, const any&) -> char;
242+ DECLARE_OPERATOR(-, char, char)
338− friend auto operator-(const char, const any&) -> char;
243+
339−
340− friend auto operator+(const string&, const any&) -> string;
244+ friend auto operator*(const any&, const any&) -> any;
341− friend auto operator+(const char* const, const any&) -> string;
342
245
246+ DECLARE_OPERATOR(*, long, long)
247+ DECLARE_OPERATOR(*, double, double)
248+ DECLARE_OPERATOR(*, char, char)
249+
250+ friend auto operator/(const any&, const any&) -> any;
251+
252+ DECLARE_OPERATOR(/, long, long)
253+ DECLARE_OPERATOR(/, double, double)
254+ DECLARE_OPERATOR(/, char, char)
255+
256+ friend auto operator%(const any&, const any&) -> any;
257+
258+ DECLARE_OPERATOR(%, long, long)
259+ DECLARE_OPERATOR(%, char, char)
260+
261+ friend auto operator-(const any&) -> any; // unary negate
343};
262};
344
263
345} // namespace PureScript
264} // namespace PureScript
346
265
266+#undef DECLARE_OPERATOR
267+#undef DECLARE_COMPARISON_OPERATOR
268+
347#endif // PureScript_HH
269#endif // PureScript_HH