@@ -30,7 +30,6 @@
3030
3131#include <functional>
3232#include <string>
33−#include <vector>
3433#include <array>
3534#include <deque>
3635#include <utility>
@@ -43,6 +42,18 @@ namespace PureScript {
4342using cstring = const char *;
4443using std::nullptr_t;
4544
45+struct symbol_generator_anchor {};
46+using symbol_t = const symbol_generator_anchor *;
47+
48+template <typename T>
49+struct symbol_generator {
50+ constexpr static symbol_generator_anchor anchor = symbol_generator_anchor{};
51+};
52+template <typename T>
53+constexpr symbol_generator_anchor symbol_generator<T>::anchor;
54+
55+#define SYMBOL(S) &symbol_generator<symbol::S>::anchor
56+
4657// Workaround for missing C++11 version in gcc
4758class runtime_error : public std::runtime_error {
4859public:
@@ -84,11 +95,13 @@ class any {
8495 };
8596 static constexpr as_thunk unthunk = as_thunk{};
8697
87− using map_pair = std::pair<const char * const, const any>;
88− using map = std::vector<map_pair WITH_ALLOCATOR(map_pair)>;
98+ using map_pair = std::pair<const symbol_t, const any>;
99+
100+ template <size_t N>
101+ using map = std::array<const map_pair, N>;
89102
90103 template <size_t N>
91− using data = std::array<any, N>;
104+ using data = std::array<const any, N>;
92105
93106 using array = std::deque<any WITH_ALLOCATOR(any)>;
94107 using fn = auto (*)(const any&) -> any;
@@ -140,7 +153,6 @@ class any {
140153 mutable eff_fn e;
141154 mutable void * u;
142155 mutable managed<std::string> s;
143− mutable managed<map> m;
144156 mutable managed<array> a;
145157 mutable managed<closure> l;
146158 mutable managed<eff_closure> k;
@@ -170,8 +182,8 @@ class any {
170182 any(const managed<std::string>& val) noexcept : type(Type::String), s(val) {}
171183 any(managed<std::string>&& val) noexcept : type(Type::String), s(std::move(val)) {}
172184
173− any(const map& val) : type(Type::Map), m(make_managed<map>(val)) {}
174− any(map&& val) noexcept : type(Type::Map), m(make_managed<map>(std::move(val))) {}
185+ template <size_t N>
186+ any(map<N>&& val) noexcept : type(Type::Map), p(make_managed<map<N>>(std::move(val))) {}
175187
176188 template <size_t N>
177189 any(data<N>&& val) noexcept : type(Type::Data), p(make_managed<data<N>>(std::move(val))) {}
@@ -216,7 +228,7 @@ class any {
216228 any(const T& val, typename std::enable_if<std::is_same<T,void*>::value>::type* = 0) noexcept
217229 : type(Type::RawPointer), u(val) {}
218230
219− any(std::nullptr_t) noexcept : type(Type::Pointer), p(nullptr) {}
231+ any(std::nullptr_t) noexcept : type(Type::RawPointer), u(nullptr) {}
220232
221233
222234#if !defined(USE_GC)
@@ -249,10 +261,10 @@ class any {
249261 case Type::RawPointer: u = other.u; break;
250262
251263 case Type::String: new (&s) managed<std::string>(move_if_rvalue<T>(other.s)); break;
252− case Type::Map: new (&m) managed<map>(move_if_rvalue<T>(other.m)); break;
253264 case Type::Array: new (&a) managed<array>(move_if_rvalue<T>(other.a)); break;
254265 case Type::Closure: new (&l) managed<closure>(move_if_rvalue<T>(other.l)); break;
255266 case Type::EffClosure: new (&k) managed<eff_closure>(move_if_rvalue<T>(other.k)); break;
267+ case Type::Map:
256268 case Type::Data:
257269 case Type::Pointer: new (&p) managed<void>(move_if_rvalue<T>(other.p)); break;
258270
@@ -263,10 +275,10 @@ class any {
263275 auto destruct() -> void {
264276 switch (type) {
265277 case Type::String: s.~managed<std::string>(); break;
266− case Type::Map: m.~managed<map>(); break;
267278 case Type::Array: a.~managed<array>(); break;
268279 case Type::Closure: l.~managed<closure>(); break;
269280 case Type::EffClosure: k.~managed<eff_closure>(); break;
281+ case Type::Map:
270282 case Type::Data:
271283 case Type::Pointer: p.~managed<void>(); break;
272284
@@ -314,14 +326,13 @@ class any {
314326 operator bool() const;
315327 operator char() const;
316328 operator cstring() const;
317− operator const map&() const;
318329 operator const array&() const;
319330
320− auto operator[](const char[]) const -> const any&;
331+ auto operator[](const symbol_t) const -> const any&;
321332 auto operator[](const size_t) const -> const any&;
322333 auto operator[](const any&) const -> const any&;
323334
324− auto contains(const char[]) const -> bool;
335+ auto contains(const symbol_t) const -> bool;
325336
326337 auto extractPointer(IF_DEBUG(const Type)) const -> void*;
327338
@@ -389,19 +400,25 @@ class any {
389400 DEFINE_OPERATOR(%, char, char)
390401
391402 friend auto operator-(const any&) -> any; // unary negate
392−};
403+
404+}; // class any
393405
394406template <typename T, typename U=void>
395−struct TypeTag {};
407+struct tag_helper {};
408+
409+template <size_t N>
410+struct tag_helper<any::map<N>> {
411+ static constexpr any::Type tag = any::Type::Map;
412+};
396413
397414template <size_t N>
398−struct TypeTag<any::data<N>> {
399− static constexpr any::Type TypeId = any::Type::Data;
415+struct tag_helper<any::data<N>> {
416+ static constexpr any::Type tag = any::Type::Data;
400417};
401418
402419template <typename T>
403−struct TypeTag<T> {
404− static constexpr any::Type TypeId = any::Type::Pointer;
420+struct tag_helper<T> {
421+ static constexpr any::Type tag = any::Type::Pointer;
405422};
406423
407424template <typename T>
@@ -413,16 +430,14 @@ inline auto cast(const any& a) ->
413430
414431template <typename T>
415432inline auto cast(const any& a) ->
416− typename std::enable_if<std::is_same<T, any::map>::value ||
417− std::is_same<T, any::array>::value, const T&>::type {
433+ typename std::enable_if<std::is_same<T, any::array>::value, const T&>::type {
418434 return a;
419435}
420436
421437template <typename T, typename = typename std::enable_if<std::is_class<T>::value>::type>
422438inline auto cast(const any& a) ->
423− typename std::enable_if<!std::is_same<T, any::map>::value &&
424− !std::is_same<T, any::array>::value, T&>::type {
425− return *static_cast<T*>(a.extractPointer(IF_DEBUG(TypeTag<T>::TypeId)));
439+ typename std::enable_if<!std::is_same<T, any::array>::value, T&>::type {
440+ return *static_cast<T*>(a.extractPointer(IF_DEBUG(tag_helper<T>::tag)));
426441}
427442
428443template <typename T>