@@ -34,17 +34,30 @@
3434#include <stdexcept>
3535#include <iso646.h> // mostly for MS Visual Studio compiler
3636
37−#define DECLARE_OPERATOR(op, ty, rty) \
38− friend auto operator op (const any&, ty) -> rty; \
39− friend auto operator op (ty, const any&) -> rty;
37+#define DEFINE_OPERATOR(op, ty, rty) \
38+ inline friend auto operator op (const any& lhs, ty rhs) -> rty { \
39+ return lhs.cast<ty>() op rhs; \
40+ } \
41+ inline friend auto operator op (ty lhs, const any& rhs) -> rty { \
42+ return lhs op rhs.cast<ty>(); \
43+ } \
44+
45+#define DEFINE_INT_OPERATOR(op, rty) \
46+ inline friend auto operator op (const any& lhs, int rhs) -> rty { \
47+ return lhs.cast<long>() op (long)rhs; \
48+ } \
49+ inline friend auto operator op (int lhs, const any& rhs) -> rty { \
50+ return (long)lhs op rhs.cast<long>(); \
51+ }
4052
4153#define DECLARE_COMPARISON_OPERATOR(op) \
4254 friend auto operator op (const any&, const any&) -> bool; \
43− DECLARE_OPERATOR(op, long, bool) \
44− DECLARE_OPERATOR(op, double, bool) \
45− DECLARE_OPERATOR(op, char, bool) \
46− DECLARE_OPERATOR(op, const char *, bool)
47−
55+ DEFINE_OPERATOR(op, long, bool) \
56+ DEFINE_OPERATOR(op, double, bool) \
57+ DEFINE_OPERATOR(op, char, bool) \
58+ DEFINE_INT_OPERATOR(op, bool) \
59+ friend auto operator op (const any&, const char * const) -> bool; \
60+ friend auto operator op (const char * const, const any&) -> bool;
4861
4962namespace PureScript {
5063
@@ -326,54 +339,49 @@ class any {
326339 DECLARE_COMPARISON_OPERATOR(>)
327340 DECLARE_COMPARISON_OPERATOR(>=)
328341
329− // For MS Visual Studio compiler: broken typed-enum workaround
330− DECLARE_OPERATOR(==, int, bool)
331− DECLARE_OPERATOR(!=, int, bool)
332−
333342 friend auto operator+(const any&, const any&) -> any;
334343
335− DECLARE_OPERATOR(+, long, long)
336− DECLARE_OPERATOR(+, double, double)
337− DECLARE_OPERATOR(+, char, char)
338− DECLARE_OPERATOR(+, const char *, std::string)
344+ DEFINE_OPERATOR(+, long, long)
345+ DEFINE_OPERATOR(+, double, double)
346+ DEFINE_OPERATOR(+, char, char)
347+ DEFINE_INT_OPERATOR(+, long)
348+ friend auto operator+(const any& lhs, const char * const rhs) -> std::string;
349+ friend auto operator+(const char * const lhs, const any& rhs) -> std::string;
339350
340351 friend auto operator-(const any&, const any&) -> any;
341352
342− DECLARE_OPERATOR(-, long, long)
343− DECLARE_OPERATOR(-, double, double)
344− DECLARE_OPERATOR(-, char, char)
353+ DEFINE_OPERATOR(-, long, long)
354+ DEFINE_OPERATOR(-, double, double)
355+ DEFINE_OPERATOR(-, char, char)
356+ DEFINE_INT_OPERATOR(-, long)
345357
346358 friend auto operator*(const any&, const any&) -> any;
347359
348− DECLARE_OPERATOR(*, long, long)
349− DECLARE_OPERATOR(*, double, double)
350− DECLARE_OPERATOR(*, char, char)
360+ DEFINE_OPERATOR(*, long, long)
361+ DEFINE_OPERATOR(*, double, double)
362+ DEFINE_OPERATOR(*, char, char)
363+ DEFINE_INT_OPERATOR(*, long)
351364
352365 friend auto operator/(const any&, const any&) -> any;
353366
354− DECLARE_OPERATOR(/, long, long)
355− DECLARE_OPERATOR(/, double, double)
356− DECLARE_OPERATOR(/, char, char)
367+ DEFINE_OPERATOR(/, long, long)
368+ DEFINE_OPERATOR(/, double, double)
369+ DEFINE_OPERATOR(/, char, char)
370+ DEFINE_INT_OPERATOR(/, long)
357371
358372 friend auto operator%(const any&, const any&) -> any;
359373
360− DECLARE_OPERATOR(%, long, long)
361− DECLARE_OPERATOR(%, char, char)
374+ DEFINE_OPERATOR(%, long, long)
375+ DEFINE_OPERATOR(%, char, char)
376+ DEFINE_INT_OPERATOR(%, long)
362377
363378 friend auto operator-(const any&) -> any; // unary negate
364379};
365380
366−// For MS Visual Studio compiler: broken typed-enum workaround
367−inline auto operator==(const any& lhs, int rhs) -> bool {
368− return lhs == (long)rhs;
369−}
370−inline auto operator!=(const any& lhs, int rhs) -> bool {
371− return lhs != (long)rhs;
372−}
373−
374381} // namespace PureScript
375382
376−#undef DECLARE_OPERATOR
383+#undef DEFINE_OPERATOR
384+#undef DEFINE_INT_OPERATOR
377385#undef DECLARE_COMPARISON_OPERATOR
378386
379387#endif // PureScript_HH