factor/vm/tagged.hpp

73 lines
1.5 KiB
C++
Raw Normal View History

2009-05-04 02:46:13 -04:00
namespace factor
{
2009-05-04 05:50:24 -04:00
template <typename T> cell tag(T *value)
2009-05-02 05:43:58 -04:00
{
return RETAG(value,tag_for(T::type_number));
}
2009-05-04 05:50:24 -04:00
inline static cell tag_dynamic(object *value)
{
2009-05-04 05:50:24 -04:00
return RETAG(value,tag_for(value->h.hi_tag()));
2009-05-02 05:43:58 -04:00
}
template <typename T>
2009-05-02 10:19:09 -04:00
struct tagged
2009-05-02 05:43:58 -04:00
{
2009-05-04 05:50:24 -04:00
cell value_;
2009-05-02 10:19:09 -04:00
2009-05-04 05:50:24 -04:00
cell value() const { return value_; }
T *untagged() const { return (T *)(UNTAG(value_)); }
2009-05-04 05:50:24 -04:00
cell type() const {
cell tag = TAG(value_);
if(tag == OBJECT_TYPE)
2009-05-04 05:50:24 -04:00
return untagged()->h.hi_tag();
else
return tag;
}
2009-05-04 05:50:24 -04:00
bool type_p(cell type_) const { return type() == type_; }
2009-05-02 10:19:09 -04:00
T *untag_check() const {
if(T::type_number != TYPE_COUNT && !type_p(T::type_number))
type_error(T::type_number,value_);
2009-05-02 10:19:09 -04:00
return untagged();
}
2009-05-04 05:50:24 -04:00
explicit tagged(cell tagged) : value_(tagged) {
2009-05-02 10:19:09 -04:00
#ifdef FACTOR_DEBUG
untag_check();
#endif
}
2009-05-04 02:46:13 -04:00
explicit tagged(T *untagged) : value_(factor::tag(untagged)) {
2009-05-02 10:19:09 -04:00
#ifdef FACTOR_DEBUG
untag_check();
#endif
2009-05-02 10:19:09 -04:00
}
T *operator->() const { return untagged(); }
2009-05-04 05:50:24 -04:00
cell *operator&() const { return &value_; }
2009-05-02 10:19:09 -04:00
const tagged<T>& operator=(const T *x) { value_ = tag(x); return *this; }
2009-05-04 05:50:24 -04:00
const tagged<T>& operator=(const cell &x) { value_ = x; return *this; }
2009-05-02 10:19:09 -04:00
bool operator==(const tagged<T> &x) { return value_ == x.value_; }
bool operator!=(const tagged<T> &x) { return value_ != x.value_; }
2009-05-02 10:19:09 -04:00
template<typename X> tagged<X> as() { return tagged<X>(value_); }
2009-05-02 05:43:58 -04:00
};
2009-05-04 05:50:24 -04:00
template <typename T> T *untag_check(cell value)
2009-05-02 05:43:58 -04:00
{
2009-05-02 10:19:09 -04:00
return tagged<T>(value).untag_check();
2009-05-02 05:43:58 -04:00
}
2009-05-04 05:50:24 -04:00
template <typename T> T *untag(cell value)
2009-05-02 05:43:58 -04:00
{
2009-05-02 10:19:09 -04:00
return tagged<T>(value).untagged();
2009-05-02 05:43:58 -04:00
}
2009-05-04 02:46:13 -04:00
}