| 
									
										
										
										
											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() const { | 
					
						
							|  |  |  |     if (Type::type_number == TYPE_COUNT) | 
					
						
							|  |  |  |       return true; | 
					
						
							| 
									
										
										
										
											2015-11-24 10:00:50 -05:00
										 |  |  |     return type() == Type::type_number; | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											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_)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   explicit tagged(cell tagged) : value_(tagged) {} | 
					
						
							|  |  |  |   explicit tagged(Type* untagged) : value_(factor::tag(untagged)) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-22 21:25:07 -05:00
										 |  |  |   void set_value(const cell ptr) { | 
					
						
							|  |  |  |     value_ = ptr; | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-11-22 21:25:07 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void set_untagged(const Type *untagged) { | 
					
						
							|  |  |  |     set_value(tag(untagged)); | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-22 21:25:07 -05:00
										 |  |  |   Type* operator->() const { return untagged(); } | 
					
						
							|  |  |  |   cell* operator&() const { return &value_; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:29:22 -04:00
										 |  |  |   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* untag(cell value) { | 
					
						
							|  |  |  |   return tagged<Type>(value).untagged(); | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:15 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |