@@ -102,21 +102,10 @@ any::~any() {
102102 }
103103};
104104
105−#define RETURN_VALUE(TYPE, VAL, FN) \
106− if (type == TYPE) { \
107− return FN(VAL); \
108− } \
109− const any* valuePtr = this; \
110− do { \
111− assert(valuePtr->type == Type::Thunk); \
112− const any& value = (*valuePtr->t)(unthunk); \
113− if (value.type == TYPE) { \
114− return FN(value.VAL); \
115− } \
116− valuePtr = &value; \
117− } while (valuePtr->type != Type::Unknown); \
118− assert(false && "Unknown value type"); \
119− return FN(VAL);
105+#define RETURN_VALUE(TYPE, ACCESSOR, INDIRECTION) \
106+ const any& variant = unthunkVariant(*this); \
107+ assert(variant.type == TYPE); \
108+ return INDIRECTION(variant.ACCESSOR); \
120109
121110template <typename T>
122111auto 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;
144133
145134template <typename T>
146135auto any::cast() const -> typename std::enable_if<std::is_same<T, string>::value, T>::type {
147− const any& val = extractValue(*this);
148− if (val.type == Type::StringLiteral) {
149− return val.r;
136+ const any& variant = unthunkVariant(*this);
137+ if (variant.type == Type::StringLiteral) {
138+ return variant.r;
150139 }
151− assert(val.type == Type::String);
152− return val.s->c_str();
140+ assert(variant.type == Type::String);
141+ return variant.s->c_str();
153142}
154143template auto any::cast<string>() const -> string;
155144
@@ -166,26 +155,12 @@ auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value
166155template auto any::cast<any::vector>() const -> const vector&;
167156
168157auto any::operator()(const any& arg) const -> any {
169− if (type == Type::Function) {
170− return (*f)(arg);
158+ const any& variant = unthunkVariant(*this);
159+ if (variant.type == Type::Closure) {
160+ return (*variant.l)(arg);
171161 }
172− if (type == Type::Closure) {
173− return (*l)(arg);
174− }
175− const any* valuePtr = this;
176− do {
177− assert(valuePtr->type == Type::Thunk);
178− const any& value = (*valuePtr->t)(unthunk);
179− if (value.type == Type::Function) {
180− return (*value.f)(arg);
181− }
182− if (value.type == Type::Closure) {
183− return (*value.l)(arg);
184− }
185− valuePtr = &value;
186− } while (valuePtr->type != Type::Unknown);
187− assert(false && "Unknown value type");
188− return nullptr;
162+ assert(variant.type == Type::Function);
163+ return (*variant.f)(arg);
189164}
190165
191166auto any::operator()(const as_thunk) const -> const any& {
@@ -194,32 +169,21 @@ auto any::operator()(const as_thunk) const -> const any& {
194169}
195170
196171auto any::operator()() const -> any {
197− if (type == Type::EffFunction) {
198− return (*e)();
199− }
200− const any* valuePtr = this;
201− do {
202− assert(valuePtr->type == Type::Thunk);
203− const any& value = (*valuePtr->t)(unthunk);
204− if (value.type == Type::EffFunction) {
205− return (*value.e)();
206− }
207− valuePtr = &value;
208− } while (valuePtr->type != Type::Unknown);
209− assert(false && "Unknown value type");
210− return nullptr;
172+ const any& variant = unthunkVariant(*this);
173+ assert(variant.type == Type::EffFunction);
174+ return (*variant.e)();
211175}
212176
213177any::operator long() const {
214− RETURN_VALUE(Type::Integer, i,)
178+ return cast<long>();
215179}
216180
217181any::operator double() const {
218− RETURN_VALUE(Type::Double, d,)
182+ return cast<double>();
219183}
220184
221185any::operator bool() const {
222− RETURN_VALUE(Type::Boolean, b,)
186+ return cast<bool>();
223187}
224188
225189any::operator string() const {
@@ -227,38 +191,30 @@ any::operator string() const {
227191}
228192
229193any::operator const map&() const {
230− RETURN_VALUE(Type::Map, m, *)
194+ return cast<map>();
231195}
232196
233197any::operator const vector&() const {
234− RETURN_VALUE(Type::Vector, v, *)
198+ return cast<vector>();
235199}
236200
237201auto any::extractPointer() const -> void* {
238202 RETURN_VALUE(Type::Pointer, p.get(),)
239203}
240204
241−auto any::extractValue(const any& a) -> const any& {
242− if (a.type != Type::Thunk) {
243− return a;
205+auto any::unthunkVariant(const any& a) -> const any& {
206+ const any * variant = &a;
207+ while (variant->type == Type::Thunk) {
208+ variant = &((*variant->t)(unthunk));
244209 }
245− const any* valuePtr = &a;
246− do {
247− const any& value = (*valuePtr->t)(unthunk);
248− if (value.type != Type::Thunk) {
249− return value;
250− }
251− valuePtr = &value;
252− } while (valuePtr->type != Type::Unknown);
253− assert(false && "Unknown value type");
254− return a;
210+ return *variant;
255211}
256212
257213auto any::operator[](const char rhs[]) const -> const any& {
258− const any& val = extractValue(*this);
259− assert(val.type == Type::Map);
260− const any::map::const_iterator begin = val.m->begin();
261− const any::map::const_iterator end = val.m->end();
214+ const any& variant = unthunkVariant(*this);
215+ assert(variant.type == Type::Map);
216+ const any::map::const_iterator begin = variant.m->begin();
217+ const any::map::const_iterator end = variant.m->end();
262218 for (any::map::const_iterator it = begin; it != end; ++it) {
263219 if (it->first == rhs) {
264220 return it->second;
@@ -273,21 +229,21 @@ auto any::operator[](const char rhs[]) const -> const any& {
273229}
274230
275231auto any::operator[](const vector::size_type rhs) const -> const any& {
276− const any& val = extractValue(*this);
277− assert(val.type == Type::Vector);
278− return (*val.v)[rhs];
232+ const any& variant = unthunkVariant(*this);
233+ assert(variant.type == Type::Vector);
234+ return (*variant.v)[rhs];
279235}
280236
281237auto any::operator[](const any& rhs) const -> const any& {
282− const any& val = extractValue(*this);
283− assert(val.type == Type::Vector);
284− return (*val.v)[rhs.cast<long>()];
238+ const any& variant = unthunkVariant(*this);
239+ assert(variant.type == Type::Vector);
240+ return (*variant.v)[rhs.cast<long>()];
285241}
286242
287243auto any::contains(const char key[]) const -> bool {
288− const any& val = extractValue(*this);
289− assert(val.type == Type::Map);
290− for (any::map::const_iterator it = val.m->begin(), end = val.m->end(); it != end; ++it) {
244+ const any& variant = unthunkVariant(*this);
245+ assert(variant.type == Type::Map);
246+ for (any::map::const_iterator it = variant.m->begin(), end = variant.m->end(); it != end; ++it) {
291247 if (it->first == key || strcmp(it->first, key) == 0) {
292248 return true;
293249 }
@@ -309,7 +265,7 @@ auto operator op (ty lhs, const any& rhs) -> rty { \
309265
310266#define DEFINE_CSTR_EQUALS_OPERATOR() \
311267 auto operator==(const any& lhs_, const char * rhs) -> bool { \
312− const any& lhs = any::extractValue(lhs_); \
268+ const any& lhs = any::unthunkVariant(lhs_); \
313269 assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String); \
314270 if (lhs.type == any::Type::StringLiteral) { \
315271 return (lhs.r == rhs) || (strcmp(lhs.r, rhs) == 0); \
@@ -317,7 +273,7 @@ auto operator op (ty lhs, const any& rhs) -> rty { \
317273 return strcmp(lhs.s->c_str(), rhs) == 0; \
318274 } \
319275 auto operator==(const char * lhs, const any& rhs_) -> bool { \
320− const any& rhs = any::extractValue(rhs_); \
276+ const any& rhs = any::unthunkVariant(rhs_); \
321277 assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String); \
322278 if (rhs.type == any::Type::StringLiteral) { \
323279 return (lhs == rhs.r) || (strcmp(lhs, rhs) == 0); \
@@ -335,8 +291,8 @@ auto operator op (ty lhs, const any& rhs) -> rty { \
335291
336292#define DEFINE_COMPARISON_OPERATOR(op) \
337293 auto operator op (const any& lhs_, const any& rhs_) -> bool { \
338− const any& lhs = any::extractValue(lhs_); \
339− const any& rhs = any::extractValue(rhs_); \
294+ const any& lhs = any::unthunkVariant(lhs_); \
295+ const any& rhs = any::unthunkVariant(rhs_); \
340296 switch (lhs.type) { \
341297 case any::Type::Integer: assert(lhs.type == any::Type::Integer); return lhs.i op rhs.i; \
342298 case any::Type::Double: assert(lhs.type == any::Type::Double); return lhs.d op rhs.d; \
@@ -379,8 +335,8 @@ DEFINE_CSTR_COMPARISON_OPERATOR(>)
379335DEFINE_CSTR_COMPARISON_OPERATOR(>=)
380336
381337auto operator+(const any& lhs_, const any& rhs_) -> any {
382− const any& lhs = any::extractValue(lhs_);
383− const any& rhs = any::extractValue(rhs_);
338+ const any& lhs = any::unthunkVariant(lhs_);
339+ const any& rhs = any::unthunkVariant(rhs_);
384340 switch (lhs.type) {
385341 case any::Type::Integer: assert(lhs.type == any::Type::Integer); return lhs.i + rhs.i;
386342 case any::Type::Double: assert(lhs.type == any::Type::Double); return lhs.d + rhs.d;
@@ -403,20 +359,20 @@ DEFINE_OPERATOR(+, double, double)
403359DEFINE_OPERATOR(+, char, char)
404360
405361auto operator+(const any& lhs_, const char * rhs) -> std::string {
406− const any& lhs = any::extractValue(lhs_);
362+ const any& lhs = any::unthunkVariant(lhs_);
407363 assert(lhs.type == any::Type::StringLiteral || lhs.type == any::Type::String);
408364 return lhs.type == any::Type::StringLiteral ? std::string(lhs.r) + rhs : *lhs.s + rhs;
409365}
410366
411367auto operator+(const char * lhs, const any& rhs_) -> std::string {
412− const any& rhs = any::extractValue(rhs_);
368+ const any& rhs = any::unthunkVariant(rhs_);
413369 assert(rhs.type == any::Type::StringLiteral || rhs.type == any::Type::String);
414370 return rhs.type == any::Type::StringLiteral ? lhs + std::string(rhs.r) : lhs + *rhs.s;
415371}
416372
417373auto operator-(const any& lhs_, const any& rhs_) -> any {
418− const any& lhs = any::extractValue(lhs_);
419− const any& rhs = any::extractValue(rhs_);
374+ const any& lhs = any::unthunkVariant(lhs_);
375+ const any& rhs = any::unthunkVariant(rhs_);
420376 assert(lhs.type == rhs.type);
421377 switch (lhs.type) {
422378 case any::Type::Integer: return lhs.i - rhs.i;
@@ -432,8 +388,8 @@ DEFINE_OPERATOR(-, double, double)
432388DEFINE_OPERATOR(-, char, char)
433389
434390auto operator*(const any& lhs_, const any& rhs_) -> any {
435− const any& lhs = any::extractValue(lhs_);
436− const any& rhs = any::extractValue(rhs_);
391+ const any& lhs = any::unthunkVariant(lhs_);
392+ const any& rhs = any::unthunkVariant(rhs_);
437393 assert(lhs.type == rhs.type);
438394 switch (lhs.type) {
439395 case any::Type::Integer: return lhs.i * rhs.i;
@@ -449,8 +405,8 @@ DEFINE_OPERATOR(*, double, double)
449405DEFINE_OPERATOR(*, char, char)
450406
451407auto operator/(const any& lhs_, const any& rhs_) -> any {
452− const any& lhs = any::extractValue(lhs_);
453− const any& rhs = any::extractValue(rhs_);
408+ const any& lhs = any::unthunkVariant(lhs_);
409+ const any& rhs = any::unthunkVariant(rhs_);
454410 assert(lhs.type == rhs.type);
455411 switch (lhs.type) {
456412 case any::Type::Integer: return lhs.i / rhs.i;
@@ -466,8 +422,8 @@ DEFINE_OPERATOR(/, double, double)
466422DEFINE_OPERATOR(/, char, char)
467423
468424auto operator%(const any& lhs_, const any& rhs_) -> any {
469− const any& lhs = any::extractValue(lhs_);
470− const any& rhs = any::extractValue(rhs_);
425+ const any& lhs = any::unthunkVariant(lhs_);
426+ const any& rhs = any::unthunkVariant(rhs_);
471427 assert(lhs.type == rhs.type);
472428 switch (lhs.type) {
473429 case any::Type::Integer: return lhs.i % rhs.i;
@@ -482,7 +438,7 @@ DEFINE_OPERATOR(%, char, char)
482438
483439// unary negate
484440auto operator-(const any& rhs_) -> any {
485− const any& rhs = any::extractValue(rhs_);
441+ const any& rhs = any::unthunkVariant(rhs_);
486442 switch (rhs.type) {
487443 case any::Type::Integer: return (- rhs.i);
488444 case any::Type::Double: return (- rhs.d);