@@ -29,6 +29,7 @@
2929#include <functional>
3030#include <string>
3131#include <vector>
32+#include <deque>
3233#include <utility>
3334#include <stdexcept>
3435
@@ -56,7 +57,7 @@ public:
5657};
5758
5859const bool undefined = false;
59−const std::vector<int>::size_type kDataCtor = 0;
60+const size_t kDataCtor = 0;
6061
6162// A variant data class designed to provide some features of dynamic typing.
6263//
@@ -73,6 +74,7 @@ class any {
7374 String,
7475 Map,
7576 Vector,
77+ Array,
7678 Function,
7779 Closure,
7880 EffFunction,
@@ -80,17 +82,22 @@ class any {
8082 Pointer
8183 };
8284
85+ private:
8386 mutable Type type = Type::Unknown;
87+ using vector = std::vector<any>;
8488
89+ public:
8590 struct as_thunk {
8691 };
8792 static constexpr as_thunk unthunk = as_thunk{};
8893
8994 using map = std::vector<std::pair<const char * const, const any>>;
90− using vector = std::vector<any>;
95+ using data = vector;
96+ using array = std::deque<any>;
9197 using fn = auto (*)(const any&) -> any;
9298 using thunk = auto (*)(const as_thunk) -> const any&;
9399
100+ private:
94101 class closure {
95102 public:
96103 virtual auto operator()(const any&) const -> any = 0;
@@ -121,6 +128,7 @@ class any {
121128 }
122129 };
123130
131+ public:
124132 template <typename T>
125133 using shared = std::shared_ptr<T>;
126134
@@ -139,6 +147,7 @@ class any {
139147 mutable shared<std::string> s;
140148 mutable shared<map> m;
141149 mutable shared<vector> v;
150+ mutable shared<array> a;
142151 mutable fn f;
143152 mutable shared<closure> l;
144153 mutable shared<eff_fn> e;
@@ -173,6 +182,9 @@ class any {
173182 any(const vector& val) : type(Type::Vector), v(make_shared<vector>(val)) {}
174183 any(vector&& val) noexcept : type(Type::Vector), v(make_shared<vector>(std::move(val))) {}
175184
185+ any(const array& val) : type(Type::Array), a(make_shared<array>(val)) {}
186+ any(array&& val) noexcept : type(Type::Array), a(make_shared<array>(std::move(val))) {}
187+
176188 template <typename T>
177189 any(const T& val, typename std::enable_if<std::is_convertible<T,fn>::value>::type* = 0)
178190 : type(Type::Function), f(val) {}
@@ -228,8 +240,14 @@ class any {
228240 template <typename T>
229241 auto cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type;
230242
243+ // These cannot be thunked
244+ template <typename T>
245+ inline auto cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
246+ return *v;
247+ }
248+
231249 template <typename T>
232− auto cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type;
250+ auto cast() const -> typename std::enable_if<std::is_same<T, array>::value, const T&>::type;
233251
234252 template <typename T>
235253 auto cast() const -> typename std::enable_if<std::is_assignable<shared<void>,T>::value, typename T::element_type*>::type {
@@ -249,9 +267,10 @@ class any {
249267 operator string() const;
250268 operator const map&() const;
251269 operator const vector&() const;
270+ operator const array&() const;
252271
253272 auto operator[](const char[]) const -> const any&;
254− auto operator[](const vector::size_type) const -> const any&;
273+ auto operator[](const size_t) const -> const any&;
255274 auto operator[](const any&) const -> const any&;
256275
257276 auto contains(const char[]) const -> bool;