/vm/tagged.hpp

http://github.com/abeaumont/factor · C++ Header · 85 lines · 68 code · 17 blank · 0 comment · 6 complexity · 362366ab1d089477e23dfb541a4d9880 MD5 · raw file

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