@@ -34,34 +34,9 @@
3434#include <stdexcept>
3535#include <iso646.h> // mostly for MS Visual Studio compiler
3636
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− }
52−
53−#define DECLARE_COMPARISON_OPERATOR(op) \
54− friend auto operator op (const any&, const any&) -> bool; \
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;
61−
6237namespace PureScript {
6338
64−using string = const char *;
39+using cstring = const char *;
6540using nullptr_t = std::nullptr_t;
6641
6742// Workaround for missing C++11 version in gcc
@@ -158,7 +133,7 @@ class any {
158133 mutable double d;
159134 mutable char c;
160135 mutable bool b;
161− mutable string r;
136+ mutable cstring r;
162137 mutable fn f;
163138 mutable shared<std::string> s;
164139 mutable shared<map> m;
@@ -280,35 +255,6 @@ class any {
280255 destruct();
281256 }
282257
283− template <typename T>
284− auto cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type;
285−
286− template <typename T>
287− auto cast() const -> typename std::enable_if<std::is_same<T, double>::value, T>::type;
288−
289− template <typename T>
290− auto cast() const -> typename std::enable_if<std::is_same<T, char>::value, T>::type;
291−
292− template <typename T>
293− auto cast() const -> typename std::enable_if<std::is_same<T, bool>::value, T>::type;
294−
295− template <typename T>
296− auto cast() const -> typename std::enable_if<std::is_same<T, string>::value, T>::type;
297−
298− template <typename T>
299− auto cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type;
300−
301− template <typename T>
302− auto cast() const -> typename std::enable_if<std::is_same<T, data>::value, const T&>::type;
303−
304− template <typename T>
305− auto cast() const -> typename std::enable_if<std::is_same<T, array>::value, const T&>::type;
306−
307− template <typename T>
308− auto cast() const -> typename std::enable_if<std::is_assignable<shared<void>,T>::value, typename T::element_type*>::type {
309− return static_cast<typename T::element_type*>(extractPointer());
310− }
311−
312258 auto operator()(const any&) const -> any;
313259 auto operator()(const as_thunk) const -> const any&;
314260 auto operator()() const -> any;
@@ -316,8 +262,8 @@ class any {
316262 operator long() const;
317263 operator double() const;
318264 operator bool() const;
319−
320− operator string() const;
265+ operator char() const;
266+ operator cstring() const;
321267 operator const map&() const;
322268 operator const data&() const;
323269 operator const array&() const;
@@ -332,6 +278,31 @@ class any {
332278
333279 static auto unthunkVariant(const any&) -> const any&;
334280
281+ #define DEFINE_OPERATOR(op, ty, rty) \
282+ inline friend auto operator op (const any& lhs, ty rhs) -> rty { \
283+ return (ty)lhs op rhs; \
284+ } \
285+ inline friend auto operator op (ty lhs, const any& rhs) -> rty { \
286+ return lhs op (ty)rhs; \
287+ } \
288+
289+ #define DEFINE_INT_OPERATOR(op, rty) \
290+ inline friend auto operator op (const any& lhs, int rhs) -> rty { \
291+ return (long)lhs op (long)rhs; \
292+ } \
293+ inline friend auto operator op (int lhs, const any& rhs) -> rty { \
294+ return (long)lhs op (long)rhs; \
295+ }
296+
297+ #define DECLARE_COMPARISON_OPERATOR(op) \
298+ friend auto operator op (const any&, const any&) -> bool; \
299+ DEFINE_OPERATOR(op, long, bool) \
300+ DEFINE_OPERATOR(op, double, bool) \
301+ DEFINE_OPERATOR(op, char, bool) \
302+ DEFINE_INT_OPERATOR(op, bool) \
303+ friend auto operator op (const any&, const char * const) -> bool; \
304+ friend auto operator op (const char * const, const any&) -> bool;
305+
335306 DECLARE_COMPARISON_OPERATOR(==)
336307 DECLARE_COMPARISON_OPERATOR(!=)
337308 DECLARE_COMPARISON_OPERATOR(<)
@@ -378,6 +349,29 @@ class any {
378349 friend auto operator-(const any&) -> any; // unary negate
379350};
380351
352+template <typename T>
353+inline auto cast(const any& a) ->
354+ typename std::enable_if<std::is_arithmetic<T>::value ||
355+ std::is_same<T,cstring>::value, T>::type {
356+ return a;
357+}
358+
359+template <typename T>
360+inline auto cast(const any& a) ->
361+ typename std::enable_if<std::is_same<T, any::map>::value ||
362+ std::is_same<T, any::data>::value ||
363+ std::is_same<T, any::array>::value, const T&>::type {
364+ return a;
365+}
366+
367+template <typename T, typename = typename std::enable_if<std::is_class<T>::value>::type>
368+inline auto cast(const any& a) ->
369+ typename std::enable_if<!std::is_same<T, any::map>::value &&
370+ !std::is_same<T, any::data>::value &&
371+ !std::is_same<T, any::array>::value, T&>::type {
372+ return *static_cast<T*>(a.extractPointer());
373+}
374+
381375} // namespace PureScript
382376
383377#undef DEFINE_OPERATOR