]> gitweb.factorcode.org Git - factor.git/blob - vm/tagged.hpp
VM: undoing 0274e889b94323fdde6919a77c494ffcfbcb2166 (#1513)
[factor.git] / vm / tagged.hpp
1 namespace factor {
2
3 template <typename Type> cell tag(Type* value) {
4   return RETAG(value, Type::type_number);
5 }
6
7 inline static cell tag_dynamic(object* value) {
8   return RETAG(value, value->type());
9 }
10
11 template <typename Type> struct tagged {
12   cell value_;
13
14   cell type() const { return TAG(value_); }
15
16   bool type_p() const {
17     if (Type::type_number == TYPE_COUNT)
18       return true;
19     return type() == Type::type_number;
20   }
21
22   cell value() const {
23     FACTOR_ASSERT(type_p());
24     return value_;
25   }
26
27   Type* untagged() const {
28     FACTOR_ASSERT(type_p());
29     return (Type*)(UNTAG(value_));
30   }
31
32   Type* untag_check(factor_vm* parent) const {
33     if (!type_p())
34       parent->type_error(Type::type_number, value_);
35     return untagged();
36   }
37
38   explicit tagged(cell tagged) : value_(tagged) {}
39   explicit tagged(Type* untagged) : value_(factor::tag(untagged)) {}
40
41   Type* operator->() const { return untagged(); }
42   cell* operator&() const { return &value_; }
43
44   const tagged<Type>& operator=(const Type* x) {
45     value_ = tag(x);
46     return *this;
47   }
48   const tagged<Type>& operator=(const cell& x) {
49     value_ = x;
50     return *this;
51   }
52
53   bool operator==(const tagged<Type>& x) { return value_ == x.value_; }
54   bool operator!=(const tagged<Type>& x) { return value_ != x.value_; }
55
56   template <typename NewType> tagged<NewType> as() {
57     return tagged<NewType>(value_);
58   }
59 };
60
61 template <typename Type> Type* factor_vm::untag_check(cell value) {
62   return tagged<Type>(value).untag_check(this);
63 }
64
65 template <typename Type> Type* untag(cell value) {
66   return tagged<Type>(value).untagged();
67 }
68
69 }