| 
									
										
										
										
											2021-08-23 23:47:29 +00:00
										 |  |  | with Ada.Unchecked_Deallocation; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package body H3.MM is | 
					
						
							|  |  |  | 	procedure Create (R: in out Ref_Counted) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Finalize (R); | 
					
						
							|  |  |  | 		R.Data := new Ref_Counted_Record; | 
					
						
							| 
									
										
										
										
											2021-10-06 08:05:21 +00:00
										 |  |  | 		R.Data.Refs := 1; | 
					
						
							| 
									
										
										
										
											2021-08-24 16:07:29 +00:00
										 |  |  | 		--System.Atomic_Counters.Initialize (R.Data.Ref_Count); -- initialize to 1
 | 
					
						
							| 
									
										
										
										
											2021-08-23 23:47:29 +00:00
										 |  |  | 	end Create; | 
					
						
							| 
									
										
										
										
											2021-10-27 16:16:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-23 23:47:29 +00:00
										 |  |  | 	procedure Create (R: in out Ref_Counted; V: in Item_Type) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		Create (R); | 
					
						
							|  |  |  | 		R.Data.Item := V; | 
					
						
							|  |  |  | 	end Create; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-24 16:19:29 +00:00
										 |  |  | 	function Get_Item_Pointer (R: in Ref_Counted) return Item_Pointer is | 
					
						
							| 
									
										
										
										
											2021-08-23 23:47:29 +00:00
										 |  |  | 	begin | 
					
						
							|  |  |  | 		if R.Data /= null then | 
					
						
							|  |  |  | 			return R.Data.Item'Access; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return null; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 	end Get_Item_Pointer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-27 15:34:30 +00:00
										 |  |  | 	function Is_Shared (R: in Ref_Counted) return Boolean is | 
					
						
							| 
									
										
										
										
											2021-08-23 23:47:29 +00:00
										 |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-10-06 08:05:21 +00:00
										 |  |  | 		--return R.Data /= null and then not System.Atomic_Counters.Is_One(R.Data.Refs);
 | 
					
						
							|  |  |  | 		return R.Data /= null and then R.Data.Refs > 1; | 
					
						
							| 
									
										
										
										
											2021-08-23 23:47:29 +00:00
										 |  |  | 	end Is_Shared; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Initialize (R: in out Ref_Counted) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		R.Data := null; | 
					
						
							|  |  |  | 	end Initialize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Adjust (R: in out Ref_Counted) is | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		if R.Data /= null then | 
					
						
							| 
									
										
										
										
											2021-10-06 08:05:21 +00:00
										 |  |  | 			R.Data.Refs := R.Data.Refs + 1; | 
					
						
							|  |  |  | 			--System.Atomic_Counters.Increment (R.Data.Refs);
 | 
					
						
							| 
									
										
										
										
											2021-08-23 23:47:29 +00:00
										 |  |  | 		end if; | 
					
						
							|  |  |  | 	end Adjust; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	procedure Finalize (R: in out Ref_Counted) is | 
					
						
							|  |  |  | 		procedure Dealloc is new Ada.Unchecked_Deallocation(Ref_Counted_Record, Ref_Counted_Pointer); | 
					
						
							|  |  |  | 	begin | 
					
						
							| 
									
										
										
										
											2021-10-27 16:16:36 +00:00
										 |  |  | 		if R.Data /= null then | 
					
						
							| 
									
										
										
										
											2021-08-24 16:07:29 +00:00
										 |  |  | 			--if System.Atomic_Counters.Decrement(R.Data.Ref_Count) then
 | 
					
						
							|  |  |  | 			--	-- The reference count reached 0
 | 
					
						
							| 
									
										
										
										
											2021-10-27 16:16:36 +00:00
										 |  |  | 			--	Dealloc (R.Data);
 | 
					
						
							| 
									
										
										
										
											2021-08-24 16:07:29 +00:00
										 |  |  | 			--	-- R.DAta must be null here
 | 
					
						
							|  |  |  | 			--end if;
 | 
					
						
							| 
									
										
										
										
											2021-10-06 08:05:21 +00:00
										 |  |  | 			if R.Data.Refs = 1 then | 
					
						
							| 
									
										
										
										
											2021-10-27 16:16:36 +00:00
										 |  |  | 				Dealloc (R.Data); | 
					
						
							| 
									
										
										
										
											2021-08-24 16:07:29 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2021-10-06 08:05:21 +00:00
										 |  |  | 				R.Data.Refs := R.Data.Refs - 1; | 
					
						
							| 
									
										
										
										
											2021-08-23 23:47:29 +00:00
										 |  |  | 			end if; | 
					
						
							|  |  |  | 		end if; | 
					
						
							|  |  |  | 	end Finalize; | 
					
						
							| 
									
										
										
										
											2021-08-24 16:07:29 +00:00
										 |  |  | end H3.MM; |