@@ -102,21 +102,10 @@ any::~any() {
105−#define RETURN_VALUE(TYPE, VAL, FN) \
105+#define RETURN_VALUE(TYPE, ACCESSOR, INDIRECTION) \
106− if (type == TYPE) { \
109− const any* valuePtr = this; \
106+ const any& variant = unthunkVariant(*this); \
111− assert(valuePtr->type == Type::Thunk); \
112− const any& value = (*valuePtr->t)(unthunk); \
113− if (value.type == TYPE) { \
107+ assert(variant.type == TYPE); \
114− return FN(value.VAL); \
108+ return INDIRECTION(variant.ACCESSOR); \
116− valuePtr = &value; \
117− } while (valuePtr->type != Type::Unknown); \
118− assert(false && "Unknown value type"); \
121template <typename T>
110template <typename T>
122auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
111auto any::cast() const -> typename std::enable_if<std::is_same<T, long>::value, T>::type {
@@ -144,12 +133,12 @@ template auto any::cast<bool>() const -> bool;
145template <typename T>
134template <typename T>
146auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, T>::type {
135auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, T>::type {
147− const any& val = extractValue(*this);
136+ const any& variant = unthunkVariant(*this);
148− if (val.type == Type::StringLiteral) {
137+ if (variant.type == Type::StringLiteral) {
149− return val.r;
138+ return variant.r;
151− assert(val.type == Type::String);
140+ assert(variant.type == Type::String);
152− return val.s->c_str();
141+ return variant.s->c_str();
154template auto any::cast<string>() const -> string;
143template auto any::cast<string>() const -> string;
@@ -166,26 +155,12 @@ auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value
166template auto any::cast<any::vector>() const -> const vector&;
155template auto any::cast<any::vector>() const -> const vector&;
168auto any::operator()(const any& arg) const -> any {
157auto any::operator()(const any& arg) const -> any {
158+ const any& variant = unthunkVariant(*this);
169− if (type == Type::Function) {
159+ if (variant.type == Type::Closure) {
170− return (*f)(arg);
160+ return (*variant.l)(arg);
172− if (type == Type::Closure) {
175− const any* valuePtr = this;
177− assert(valuePtr->type == Type::Thunk);
178− const any& value = (*valuePtr->t)(unthunk);
179− if (value.type == Type::Function) {
162+ assert(variant.type == Type::Function);
180− return (*value.f)(arg);
163+ return (*variant.f)(arg);
182− if (value.type == Type::Closure) {
183− return (*value.l)(arg);
186− } while (valuePtr->type != Type::Unknown);
187− assert(false && "Unknown value type");
191auto any::operator()(const as_thunk) const -> const any& {
166auto any::operator()(const as_thunk) const -> const any& {
@@ -194,32 +169,21 @@ auto any::operator()(const as_thunk) const -> const any& {
196auto any::operator()() const -> any {
171auto any::operator()() const -> any {
197− if (type == Type::EffFunction) {
200− const any* valuePtr = this;
172+ const any& variant = unthunkVariant(*this);
202− assert(valuePtr->type == Type::Thunk);
203− const any& value = (*valuePtr->t)(unthunk);
204− if (value.type == Type::EffFunction) {
173+ assert(variant.type == Type::EffFunction);
205− return (*value.e)();
174+ return (*variant.e)();
208− } while (valuePtr->type != Type::Unknown);
209− assert(false && "Unknown value type");
213any::operator long() const {
177any::operator long() const {
214− RETURN_VALUE(Type::Integer, i,)
178+ return cast<long>();
217any::operator double() const {
181any::operator double() const {
218− RETURN_VALUE(Type::Double, d,)
182+ return cast<double>();
221any::operator bool() const {
185any::operator bool() const {
222− RETURN_VALUE(Type::Boolean, b,)
186+ return cast<bool>();
225any::operator string() const {
189any::operator string() const {
@@ -227,38 +191,30 @@ any::operator string() const {
229any::operator const map&() const {
193any::operator const map&() const {
230− RETURN_VALUE(Type::Map, m, *)
194+ return cast<map>();
233any::operator const vector&() const {
197any::operator const vector&() const {
234− RETURN_VALUE(Type::Vector, v, *)
198+ return cast<vector>();
237auto any::extractPointer() const -> void* {
201auto any::extractPointer() const -> void* {
238 RETURN_VALUE(Type::Pointer, p.get(),)
202 RETURN_VALUE(Type::Pointer, p.get(),)
241−auto any::extractValue(const any& a) -> const any& {
205+auto any::unthunkVariant(const any& a) -> const any& {
206+ const any * variant = &a;
242− if (a.type != Type::Thunk) {
207+ while (variant->type == Type::Thunk) {
243− return a;
208+ variant = &((*variant->t)(unthunk));
245− const any* valuePtr = &a;
247− const any& value = (*valuePtr->t)(unthunk);
248− if (value.type != Type::Thunk) {
249− return value;
210+ return *variant;
252− } while (valuePtr->type != Type::Unknown);
253− assert(false && "Unknown value type");
257auto any::operator[](const char rhs[]) const -> const any& {
213auto any::operator[](const char rhs[]) const -> const any& {
258− const any& val = extractValue(*this);
214+ const any& variant = unthunkVariant(*this);
259− assert(val.type == Type::Map);
215+ assert(variant.type == Type::Map);
260− const any::map::const_iterator begin = val.m->begin();
216+ const any::map::const_iterator begin = variant.m->begin();
261− const any::map::const_iterator end = val.m->end();
217+ const any::map::const_iterator end = variant.m->end();
262 for (any::map::const_iterator it = begin; it != end; ++it) {
218 for (any::map::const_iterator it = begin; it != end; ++it) {
263 if (it->first == rhs) {
219 if (it->first == rhs) {
264 return it->second;
220 return it->second;
@@ -273,21 +229,21 @@ auto any::operator[](const char rhs[]) const -> const any& {
275auto any::operator[](const vector::size_type rhs) const -> const any& {
231auto any::operator[](const vector::size_type rhs) const -> const any& {
276− const any& val = extractValue(*this);
232+ const any& variant = unthunkVariant(*this);
277− assert(val.type == Type::Vector);
233+ assert(variant.type == Type::Vector);
278− return (*val.v)[rhs];
234+ return (*variant.v)[rhs];
281auto any::operator[](const any& rhs) const -> const any& {
237auto any::operator[](const any& rhs) const -> const any& {
282− const any& val = extractValue(*this);
238+ const any& variant = unthunkVariant(*this);
283− assert(val.type == Type::Vector);
239+ assert(variant.type == Type::Vector);
284− return (*val.v)[rhs.cast<long>()];
240+ return (*variant.v)[rhs.cast<long>()];
287auto any::contains(const char key[]) const -> bool {
243auto any::contains(const char key[]) const -> bool {
288− const any& val = extractValue(*this);
244+ const any& variant = unthunkVariant(*this);
289− assert(val.type == Type::Map);
245+ assert(variant.type == Type::Map);
290− for (any::map::const_iterator it = val.m->begin(), end = val.m->end(); it != end; ++it) {
246+ for (any::map::const_iterator it = variant.m->begin(), end = variant.m->end(); it != end; ++it) {
291 if (it->first == key || strcmp(it->first, key) == 0) {
247 if (it->first == key || strcmp(it->first, key) == 0) {
292 return true;
248 return true;
@@ -309,7 +265,7 @@ auto operator op (ty lhs, const any& rhs) -> rty { \
310#define DEFINE_CSTR_EQUALS_OPERATOR() \
266#define DEFINE_CSTR_EQUALS_OPERATOR() \
311 auto operator==(const any& lhs_, const char * rhs) -> bool { \
267 auto operator==(const any& lhs_, const char * rhs) -> bool { \
312− const any& lhs = any::extractValue(lhs_); \
268+ const any& lhs = any::unthunkVariant(lhs_); \
313 assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String); \
269 assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String); \
314 if (lhs.type == any::Type::StringLiteral) { \
270 if (lhs.type == any::Type::StringLiteral) { \
315 return (lhs.r == rhs) || (strcmp(lhs.r, rhs) == 0); \
271 return (lhs.r == rhs) || (strcmp(lhs.r, rhs) == 0); \
@@ -317,7 +273,7 @@ auto operator op (ty lhs, const any& rhs) -> rty { \
317 return strcmp(lhs.s->c_str(), rhs) == 0; \
273 return strcmp(lhs.s->c_str(), rhs) == 0; \
319 auto operator==(const char * lhs, const any& rhs_) -> bool { \
275 auto operator==(const char * lhs, const any& rhs_) -> bool { \
320− const any& rhs = any::extractValue(rhs_); \
276+ const any& rhs = any::unthunkVariant(rhs_); \
321 assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String); \
277 assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String); \
322 if (rhs.type == any::Type::StringLiteral) { \
278 if (rhs.type == any::Type::StringLiteral) { \
323 return (lhs == rhs.r) || (strcmp(lhs, rhs) == 0); \
279 return (lhs == rhs.r) || (strcmp(lhs, rhs) == 0); \
@@ -335,8 +291,8 @@ auto operator op (ty lhs, const any& rhs) -> rty { \
336#define DEFINE_COMPARISON_OPERATOR(op) \
292#define DEFINE_COMPARISON_OPERATOR(op) \
337 auto operator op (const any& lhs_, const any& rhs_) -> bool { \
293 auto operator op (const any& lhs_, const any& rhs_) -> bool { \
338− const any& lhs = any::extractValue(lhs_); \
294+ const any& lhs = any::unthunkVariant(lhs_); \
339− const any& rhs = any::extractValue(rhs_); \
295+ const any& rhs = any::unthunkVariant(rhs_); \
340 switch (lhs.type) { \
296 switch (lhs.type) { \
341 case any::Type::Integer: assert(lhs.type == any::Type::Integer); return lhs.i op rhs.i; \
297 case any::Type::Integer: assert(lhs.type == any::Type::Integer); return lhs.i op rhs.i; \
342 case any::Type::Double: assert(lhs.type == any::Type::Double); return lhs.d op rhs.d; \
298 case any::Type::Double: assert(lhs.type == any::Type::Double); return lhs.d op rhs.d; \
@@ -379,8 +335,8 @@ DEFINE_CSTR_COMPARISON_OPERATOR(>)
379DEFINE_CSTR_COMPARISON_OPERATOR(>=)
335DEFINE_CSTR_COMPARISON_OPERATOR(>=)
381auto operator+(const any& lhs_, const any& rhs_) -> any {
337auto operator+(const any& lhs_, const any& rhs_) -> any {
382− const any& lhs = any::extractValue(lhs_);
338+ const any& lhs = any::unthunkVariant(lhs_);
383− const any& rhs = any::extractValue(rhs_);
339+ const any& rhs = any::unthunkVariant(rhs_);
384 switch (lhs.type) {
340 switch (lhs.type) {
385 case any::Type::Integer: assert(lhs.type == any::Type::Integer); return lhs.i + rhs.i;
341 case any::Type::Integer: assert(lhs.type == any::Type::Integer); return lhs.i + rhs.i;
386 case any::Type::Double: assert(lhs.type == any::Type::Double); return lhs.d + rhs.d;
342 case any::Type::Double: assert(lhs.type == any::Type::Double); return lhs.d + rhs.d;
@@ -403,20 +359,20 @@ DEFINE_OPERATOR(+, double, double)
403DEFINE_OPERATOR(+, char, char)
359DEFINE_OPERATOR(+, char, char)
405auto operator+(const any& lhs_, const char * rhs) -> std::string {
361auto operator+(const any& lhs_, const char * rhs) -> std::string {
406− const any& lhs = any::extractValue(lhs_);
362+ const any& lhs = any::unthunkVariant(lhs_);
407 assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String);
363 assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String);
408 return lhs.type == any::Type::StringLiteral ? std::string(lhs.r) + rhs : *lhs.s + rhs;
364 return lhs.type == any::Type::StringLiteral ? std::string(lhs.r) + rhs : *lhs.s + rhs;
411auto operator+(const char * lhs, const any& rhs_) -> std::string {
367auto operator+(const char * lhs, const any& rhs_) -> std::string {
412− const any& rhs = any::extractValue(rhs_);
368+ const any& rhs = any::unthunkVariant(rhs_);
413 assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String);
369 assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String);
414 return rhs.type == any::Type::StringLiteral ? lhs + std::string(rhs.r) : lhs + *rhs.s;
370 return rhs.type == any::Type::StringLiteral ? lhs + std::string(rhs.r) : lhs + *rhs.s;
417auto operator-(const any& lhs_, const any& rhs_) -> any {
373auto operator-(const any& lhs_, const any& rhs_) -> any {
418− const any& lhs = any::extractValue(lhs_);
374+ const any& lhs = any::unthunkVariant(lhs_);
419− const any& rhs = any::extractValue(rhs_);
375+ const any& rhs = any::unthunkVariant(rhs_);
420 assert(lhs.type == rhs.type);
376 assert(lhs.type == rhs.type);
421 switch (lhs.type) {
377 switch (lhs.type) {
422 case any::Type::Integer: return lhs.i - rhs.i;
378 case any::Type::Integer: return lhs.i - rhs.i;
@@ -432,8 +388,8 @@ DEFINE_OPERATOR(-, double, double)
432DEFINE_OPERATOR(-, char, char)
388DEFINE_OPERATOR(-, char, char)
434auto operator*(const any& lhs_, const any& rhs_) -> any {
390auto operator*(const any& lhs_, const any& rhs_) -> any {
435− const any& lhs = any::extractValue(lhs_);
391+ const any& lhs = any::unthunkVariant(lhs_);
436− const any& rhs = any::extractValue(rhs_);
392+ const any& rhs = any::unthunkVariant(rhs_);
437 assert(lhs.type == rhs.type);
393 assert(lhs.type == rhs.type);
438 switch (lhs.type) {
394 switch (lhs.type) {
439 case any::Type::Integer: return lhs.i * rhs.i;
395 case any::Type::Integer: return lhs.i * rhs.i;
@@ -449,8 +405,8 @@ DEFINE_OPERATOR(*, double, double)
449DEFINE_OPERATOR(*, char, char)
405DEFINE_OPERATOR(*, char, char)
451auto operator/(const any& lhs_, const any& rhs_) -> any {
407auto operator/(const any& lhs_, const any& rhs_) -> any {
452− const any& lhs = any::extractValue(lhs_);
408+ const any& lhs = any::unthunkVariant(lhs_);
453− const any& rhs = any::extractValue(rhs_);
409+ const any& rhs = any::unthunkVariant(rhs_);
454 assert(lhs.type == rhs.type);
410 assert(lhs.type == rhs.type);
455 switch (lhs.type) {
411 switch (lhs.type) {
456 case any::Type::Integer: return lhs.i / rhs.i;
412 case any::Type::Integer: return lhs.i / rhs.i;
@@ -466,8 +422,8 @@ DEFINE_OPERATOR(/, double, double)
466DEFINE_OPERATOR(/, char, char)
422DEFINE_OPERATOR(/, char, char)
468auto operator%(const any& lhs_, const any& rhs_) -> any {
424auto operator%(const any& lhs_, const any& rhs_) -> any {
469− const any& lhs = any::extractValue(lhs_);
425+ const any& lhs = any::unthunkVariant(lhs_);
470− const any& rhs = any::extractValue(rhs_);
426+ const any& rhs = any::unthunkVariant(rhs_);
471 assert(lhs.type == rhs.type);
427 assert(lhs.type == rhs.type);
472 switch (lhs.type) {
428 switch (lhs.type) {
473 case any::Type::Integer: return lhs.i % rhs.i;
429 case any::Type::Integer: return lhs.i % rhs.i;
@@ -482,7 +438,7 @@ DEFINE_OPERATOR(%, char, char)
483// unary negate
439// unary negate
484auto operator-(const any& rhs_) -> any {
440auto operator-(const any& rhs_) -> any {
485− const any& rhs = any::extractValue(rhs_);
441+ const any& rhs = any::unthunkVariant(rhs_);
486 switch (rhs.type) {
442 switch (rhs.type) {
487 case any::Type::Integer: return (- rhs.i);
443 case any::Type::Integer: return (- rhs.i);
488 case any::Type::Double: return (- rhs.d);
444 case any::Type::Double: return (- rhs.d);