template CELL tag(T *value) { if(T::type_number < HEADER_TYPE) return RETAG(value,T::type_number); else return RETAG(value,OBJECT_TYPE); } template struct tagged { CELL value_; T *untag_check() const { if(T::type_number != TYPE_COUNT) type_check(T::type_number,value_); return untagged(); } explicit tagged(CELL tagged) : value_(tagged) { #ifdef FACTOR_DEBUG untag_check(); #endif } explicit tagged(T *untagged) : value_(::tag(untagged)) { #ifdef FACTOR_DEBUG untag_check(); #endif } CELL value() const { return value_; } T *untagged() const { return (T *)(UNTAG(value_)); } T *operator->() const { return untagged(); } CELL *operator&() const { return &value_; } const tagged& operator=(const T *x) { value_ = tag(x); return *this; } const tagged& operator=(const CELL &x) { value_ = x; return *this; } CELL type() const { return type_of(value_); } bool isa(CELL type_) const { return type() == type_; } template tagged as() { return tagged(value_); } }; template T *untag_check(CELL value) { return tagged(value).untag_check(); } template T *untagged(CELL value) { return tagged(value).untagged(); }