namespace factor { template cell tag(Type* value) { return RETAG(value, Type::type_number); } inline static cell tag_dynamic(object* value) { return RETAG(value, value->type()); } template struct tagged { cell value_; cell type() const { return TAG(value_); } bool type_p(cell type_) const { return type() == type_; } bool type_p() const { if (Type::type_number == TYPE_COUNT) return true; else return type_p(Type::type_number); } cell value() const { FACTOR_ASSERT(type_p()); return value_; } Type* untagged() const { FACTOR_ASSERT(type_p()); return (Type*)(UNTAG(value_)); } Type* untag_check(factor_vm* parent) const { if (!type_p()) parent->type_error(Type::type_number, value_); return untagged(); } explicit tagged(cell tagged) : value_(tagged) {} explicit tagged(Type* untagged) : value_(factor::tag(untagged)) {} Type* operator->() const { return untagged(); } cell* operator&() const { return &value_; } const tagged& operator=(const Type* x) { value_ = tag(x); return *this; } const tagged& operator=(const cell& x) { value_ = x; return *this; } bool operator==(const tagged& x) { return value_ == x.value_; } bool operator!=(const tagged& x) { return value_ != x.value_; } template tagged as() { return tagged(value_); } }; template Type* factor_vm::untag_check(cell value) { return tagged(value).untag_check(this); } template Type* untag(cell value) { return tagged(value).untagged(); } }