with Ada.Finalization, Ada.Unchecked_Deallocation;

generic

  type Object is private;

package Safe_Pointers.On_Definite_Types is

  type Safe_Pointer is private;

  function Null_Pointer return Safe_Pointer;

  function "=" (Left, Right: Safe_Pointer) return Boolean;

  procedure Allocate   (Pointer: in out Safe_Pointer);
  procedure Allocate   (Pointer: in out Safe_Pointer; Value : in     Object);
  procedure Deallocate (Pointer: in out Safe_Pointer);
  procedure Alias      (Pointer: in out Safe_Pointer; Value : access Object);
  procedure Assign     (Pointer: in     Safe_Pointer; Value : in     Object);
  function  Value      (Pointer:        Safe_Pointer)         return Object;

private

  type Object_Pointer is access all Object;  pragma Controlled (Object_Pointer);
  procedure Free is new Ada.Unchecked_Deallocation (Object, Object_Pointer);

  type Track is record
    Object: Object_Pointer;
    Count : Natural := 0;
    Pool_Element: Boolean := True;
  end record;

  type Tracker is access Track;  pragma Controlled (Tracker);
  procedure Free is new Ada.Unchecked_Deallocation (Track, Tracker);

  Null_Track: constant Tracker := new Track;

  type Safe_Pointer is new Ada.Finalization.Controlled with record
    Track: Tracker := Null_Track;
  end record;

  procedure Adjust    (Pointer: in out Safe_Pointer);
  procedure Finalize  (Pointer: in out Safe_Pointer);

end Safe_Pointers.On_Definite_Types;

Back to text.