factor/vm/tagged.hpp

60 lines
1.3 KiB
C++

namespace factor {
template <typename Type> cell tag(Type* value) {
return RETAG(value, Type::type_number);
}
inline static cell tag_dynamic(object* value) {
return RETAG(value, value->type());
}
template <typename Type> struct tagged {
cell value_;
cell type() const { return TAG(value_); }
bool type_p() const {
if (Type::type_number == TYPE_COUNT)
return true;
return type() == Type::type_number;
}
cell value() const {
FACTOR_ASSERT(type_p());
return value_;
}
Type* untagged() const {
FACTOR_ASSERT(type_p());
return (Type*)(UNTAG(value_));
}
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<Type>& operator=(const Type* x) {
value_ = tag(x);
return *this;
}
const tagged<Type>& operator=(const cell& x) {
value_ = x;
return *this;
}
bool operator==(const tagged<Type>& x) { return value_ == x.value_; }
bool operator!=(const tagged<Type>& x) { return value_ != x.value_; }
template <typename NewType> tagged<NewType> as() {
return tagged<NewType>(value_);
}
};
template <typename Type> Type* untag(cell value) {
return tagged<Type>(value).untagged();
}
}