@@ -44,6 +44,7 @@
44namespace PureScript {
44namespace PureScript {
46using cstring = const char *;
46using cstring = const char *;
47using std::nullptr_t;
48using std::nullptr_t;
48using std::runtime_error;
49using std::runtime_error;
@@ -163,7 +164,7 @@ class any {
163 mutable fn f;
164 mutable fn f;
164 mutable eff_fn e;
165 mutable eff_fn e;
165 mutable void * u;
166 mutable void * u;
166− mutable managed<std::string> s;
167+ mutable managed<string> s;
167 mutable managed<array> a;
168 mutable managed<array> a;
168 mutable managed<Closure> l;
169 mutable managed<Closure> l;
169 mutable managed<EffClosure> k;
170 mutable managed<EffClosure> k;
@@ -186,13 +187,13 @@ class any {
187 template <size_t N>
188 template <size_t N>
188 any(const char (&val)[N]) noexcept : tag(Tag::StringLiteral), r(val) {}
189 any(const char (&val)[N]) noexcept : tag(Tag::StringLiteral), r(val) {}
189− any(char * val) : tag(Tag::String), s(make_managed<std::string>(val)) {}
190+ any(char * val) : tag(Tag::String), s(make_managed<string>(val)) {}
191− any(const std::string& val) : tag(Tag::String), s(make_managed<std::string>(val)) {}
192+ any(const string& val) : tag(Tag::String), s(make_managed<string>(val)) {}
192− any(std::string&& val) noexcept : tag(Tag::String), s(make_managed<std::string>(std::move(val))) {}
193+ any(string&& val) noexcept : tag(Tag::String), s(make_managed<string>(std::move(val))) {}
194− any(const managed<std::string>& val) noexcept : tag(Tag::String), s(val) {}
195+ any(const managed<string>& val) noexcept : tag(Tag::String), s(val) {}
195− any(managed<std::string>&& val) noexcept : tag(Tag::String), s(std::move(val)) {}
196+ any(managed<string>&& val) noexcept : tag(Tag::String), s(std::move(val)) {}
197 template <size_t N>
198 template <size_t N>
198 any(map<N>&& val) noexcept : tag(Tag::Map), p(make_managed<map<N>>(std::move(val))) {}
199 any(map<N>&& val) noexcept : tag(Tag::Map), p(make_managed<map<N>>(std::move(val))) {}
@@ -272,13 +273,13 @@ class any {
272 case Tag::EffFunction: e = other.e; break;
273 case Tag::EffFunction: e = other.e; break;
273 case Tag::RawPointer: u = other.u; break;
274 case Tag::RawPointer: u = other.u; break;
275− case Tag::String: new (&s) managed<std::string>(move_if_rvalue<T>(other.s)); break;
276+ case Tag::String: new (&s) managed<string>(move_if_rvalue<T>(other.s)); break;
276− case Tag::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
277+ case Tag::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
277− case Tag::Closure: new (&l) managed<Closure>(move_if_rvalue<T>(other.l)); break;
278+ case Tag::Closure: new (&l) managed<Closure>(move_if_rvalue<T>(other.l)); break;
278 case Tag::EffClosure: new (&k) managed<EffClosure>(move_if_rvalue<T>(other.k)); break;
279 case Tag::EffClosure: new (&k) managed<EffClosure>(move_if_rvalue<T>(other.k)); break;
279 case Tag::Map:
280 case Tag::Map:
280 case Tag::Data:
281 case Tag::Data:
281− case Tag::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
282+ case Tag::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
283 default: assert(false && "Bad 'any' tag"); break;
284 default: assert(false && "Bad 'any' tag"); break;
@@ -286,13 +287,13 @@ class any {
287 auto destruct() -> void {
288 auto destruct() -> void {
288 switch (tag) {
289 switch (tag) {
289− case Tag::String: s.~managed<std::string>(); break;
290+ case Tag::String: s.~managed<string>(); break;
290− case Tag::Array: a.~managed<array>(); break;
291+ case Tag::Array: a.~managed<array>(); break;
291− case Tag::Closure: l.~managed<Closure>(); break;
292+ case Tag::Closure: l.~managed<Closure>(); break;
292− case Tag::EffClosure: k.~managed<EffClosure>(); break;
293+ case Tag::EffClosure: k.~managed<EffClosure>(); break;
293 case Tag::Map:
294 case Tag::Map:
294 case Tag::Data:
295 case Tag::Data:
295− case Tag::Pointer: p.~managed<void>(); break;
296+ case Tag::Pointer: p.~managed<void>(); break;
297 default: break;
298 default: break;
@@ -386,8 +387,8 @@ class any {
386 DEFINE_OPERATOR(+, int, int)
387 DEFINE_OPERATOR(+, int, int)
387 DEFINE_OPERATOR(+, double, double)
388 DEFINE_OPERATOR(+, double, double)
388 DEFINE_OPERATOR(+, char, char)
389 DEFINE_OPERATOR(+, char, char)
389− friend auto operator+(const any& lhs, const char * const rhs) -> std::string;
390+ friend auto operator+(const any& lhs, const char * const rhs) -> string;
390− friend auto operator+(const char * const lhs, const any& rhs) -> std::string;
391+ friend auto operator+(const char * const lhs, const any& rhs) -> string;
392 friend auto operator-(const any&, const any&) -> any;
393 friend auto operator-(const any&, const any&) -> any;
@@ -461,6 +462,14 @@ inline auto cast(const any& a) ->
461 return *static_cast<T*>(a.extractPointer(IF_DEBUG(Private::TagHelper<T>::tag)));
462 return *static_cast<T*>(a.extractPointer(IF_DEBUG(Private::TagHelper<T>::tag)));
465+template <typename T,
466+ typename = typename std::enable_if<std::is_pointer<T>::value &&
467+ !std::is_same<T,void*>::value &&
468+ !std::is_same<T,cstring>::value>::type>
469+inline auto cast(const any& a) -> T {
470+ return static_cast<T>(a.extractPointer(IF_DEBUG(Private::TagHelper<T>::tag)));
464template <typename T>
473template <typename T>
465inline auto cast(const any& a) ->
474inline auto cast(const any& a) ->
466 typename std::enable_if<std::is_same<void*, T>::value, T>::type {
475 typename std::enable_if<std::is_same<void*, T>::value, T>::type {
@@ -496,8 +505,45 @@ namespace map {
496 inline auto get(const Private::Symbol key, const any& a) -> const any& {
505 inline auto get(const Private::Symbol key, const any& a) -> const any& {
497 return get(key, cast<any::map<unknown_size>>(a));
506 return get(key, cast<any::map<unknown_size>>(a));
509+ #define P(N) any::map_pair&& arg ## N
510+ #define T(N) any::map<N+1>
511+ #define E(N) std::forward<decltype(arg ## N)>(arg ## N)
512+ #define M(...) {{ __VA_ARGS__, { nullptr, nullptr } }}
514+ inline auto make(P(1)) -> T(1) {
515+ return T(1) M(E(1));
517+ inline auto make(P(1), P(2)) -> T(2) {
518+ return T(2) M(E(1), E(2));
520+ inline auto make(P(1), P(2), P(3)) -> T(3) {
521+ return T(3) M(E(1), E(2), E(3));
523+ inline auto make(P(1), P(2), P(3), P(4)) -> T(4) {
524+ return T(4) M(E(1), E(2), E(3), E(4));
526+ inline auto make(P(1), P(2), P(3), P(4), P(5)) -> T(5) {
527+ return T(5) M(E(1), E(2), E(3), E(4), E(5));
529+ inline auto make(P(1), P(2), P(3), P(4), P(5), P(6)) -> T(6) {
530+ return T(6) M(E(1), E(2), E(3), E(4), E(5), E(6));
532+ inline auto make(P(1), P(2), P(3), P(4), P(5), P(6), P(7)) -> T(7) {
533+ return T(7) M(E(1), E(2), E(3), E(4), E(5), E(6), E(7));
535+ inline auto make(P(1), P(2), P(3), P(4), P(5), P(6), P(7), P(8)) -> T(8) {
536+ return T(8) M(E(1), E(2), E(3), E(4), E(5), E(6), E(7), E(8));
545+namespace record = map;
501namespace data {
547namespace data {
502 template <size_t N, typename T>
548 template <size_t N, typename T>
503 inline auto get(const T& a) ->
549 inline auto get(const T& a) ->