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