-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
controlled types: idiom for refcounting
- Loading branch information
1 parent
3121390
commit 729ef05
Showing
2 changed files
with
76 additions
and
0 deletions.
There are no files selected for viewing
75 changes: 75 additions & 0 deletions
75
courses/fundamentals_of_ada/260_controlled_types/10-idiom_refcounting.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
========================================= | ||
Reference Counting Using Controlled Types | ||
========================================= | ||
|
||
--------------- | ||
Global Overview | ||
--------------- | ||
|
||
* Idiom for counting object references | ||
|
||
- Safe deallocation | ||
- No memory leak | ||
- Efficient | ||
- All :ada:`access` must then be using it | ||
|
||
* A refcounted type derives from :ada:`Refcounted` | ||
|
||
- Tagged | ||
- Get a :ada:`Ref` through :ada:`Set` | ||
- Turn a :ada:`Ref` into an :ada:`access` through :ada:`Get` | ||
|
||
.. code:: Ada | ||
package Ref_Counter is | ||
type Refcounted is abstract tagged private; | ||
procedure Free (Self : in out Refcounted) is null; | ||
type Refcounted_Access is access all Refcounted'Class; | ||
type Ref is tagged private; | ||
procedure Set (Self : in out Ref; Data : Refcounted'Class); | ||
function Get (Self : Ref) return Refcounted_Access; | ||
procedure Finalize (P : in out Ref); | ||
procedure Adjust (P : in out Ref); | ||
private | ||
type Refcounted is abstract tagged record | ||
Refcount : Integer := 0; | ||
end record; | ||
type Ref is new Ada.Finalization.Controlled with record | ||
Data : Refcounted_Access; | ||
end record; | ||
---------------------- | ||
Implementation Details | ||
---------------------- | ||
|
||
* :ada:`Set` is safe | ||
|
||
- :ada:`Ref` default value is :ada:`null` | ||
- Clears up any previously used :ada:`Ref` | ||
|
||
.. code:: Ada | ||
procedure Set (Self : in out Ref; Data : Refcounted'Class) is | ||
D : constant Refcounted_Access := new Refcounted'Class'(Data); | ||
begin | ||
if Self.Data /= null then | ||
Finalize (Self); -- decrement old reference count | ||
end if; | ||
Self.Data := D; | ||
Adjust (Self); -- increment reference count (set to 1) | ||
end Set; | ||
* :ada:`Adjust` called for all new references | ||
|
||
.. code:: Ada | ||
overriding procedure Adjust (P : in out Ref) is | ||
begin | ||
if P.Data /= null then | ||
P.Data.Refcount := P.Data.Refcount + 1; | ||
end if; | ||
end Adjust; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters