with Ada.Finalization, Ada.Unchecked_Deallocation;
use Ada.Finalization;

pragma Elaborate_All (Ada.Finalization,Ada.Unchecked_Deallocation);

generic

  type Item is private;

package Recycling is  --- recycle instead of deallocate

  type Linked_Data;
  type LD_Pointer is access Linked_Data;

  type Linked_Data is  --- do not create directly (defeats the purpose)
    record
      Data: Item;
      Link: LD_Pointer := null;
    end record;

  protected type Protected_Data is
    procedure Allocate(L: out LD_Pointer);
    procedure Recycle(L: in LD_Pointer);
    procedure Free_All;
  private
    Next: LD_Pointer := null;
  end Protected_Data;

  procedure Deallocate is new Ada.Unchecked_Deallocation(Linked_Data,LD_Pointer);

  type Controlled_Protected_Data is new Limited_Controlled with
    record
      P: Protected_Data;
    end record;

  overriding procedure Finalize(C: in out Controlled_Protected_Data); -- calls C.P.Free_All

end Recycling;
