60 lines
1.3 KiB
C++
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();
|
|
}
|
|
|
|
}
|