| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  | namespace factor { | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  | template <typename Type> cell tag(Type* value) { | 
					
						
							|  |  |  |   return RETAG(value, Type::type_number); | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  | inline static cell tag_dynamic(object* value) { | 
					
						
							|  |  |  |   return RETAG(value, value->type()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:43:58 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  | template <typename Type> struct tagged { | 
					
						
							|  |  |  |   cell value_; | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  |   cell type() const { return TAG(value_); } | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  |   bool type_p(cell type_) const { return type() == type_; } | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  |   bool type_p() const { | 
					
						
							|  |  |  |     if (Type::type_number == TYPE_COUNT) | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       return type_p(Type::type_number); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  |   cell value() const { | 
					
						
							|  |  |  |     FACTOR_ASSERT(type_p()); | 
					
						
							|  |  |  |     return value_; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  |   Type* untagged() const { | 
					
						
							|  |  |  |     FACTOR_ASSERT(type_p()); | 
					
						
							|  |  |  |     return (Type*)(UNTAG(value_)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Type* untag_check(factor_vm* parent) const { | 
					
						
							|  |  |  |     if (!type_p()) | 
					
						
							|  |  |  |       parent->type_error(Type::type_number, value_); | 
					
						
							|  |  |  |     return untagged(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   explicit tagged(cell tagged) : value_(tagged) {} | 
					
						
							|  |  |  |   explicit tagged(Type* untagged) : value_(factor::tag(untagged)) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Type* operator->() const { return untagged(); } | 
					
						
							|  |  |  |   cell* operator&() const { return &value_; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const tagged<Type>& operator=(const Type* x) { | 
					
						
							|  |  |  |     value_ = tag(x); | 
					
						
							|  |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const tagged<Type>& operator=(const cell& x) { | 
					
						
							|  |  |  |     value_ = x; | 
					
						
							|  |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool operator==(const tagged<Type>& x) { return value_ == x.value_; } | 
					
						
							|  |  |  |   bool operator!=(const tagged<Type>& x) { return value_ != x.value_; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   template <typename NewType> tagged<NewType> as() { | 
					
						
							|  |  |  |     return tagged<NewType>(value_); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:15 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  | template <typename Type> Type* factor_vm::untag_check(cell value) { | 
					
						
							|  |  |  |   return tagged<Type>(value).untag_check(this); | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:15 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  | template <typename Type> Type* untag(cell value) { | 
					
						
							|  |  |  |   return tagged<Type>(value).untagged(); | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:15 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |