-- -- Copyright (C) 2014-2022, AdaCore -- SPDX-License-Identifier: Apache-2.0 -- -- This package provides a simple implementation for boxing types: types that -- are dynamically allocated, handled by reference and with automatic memory -- management thanks to reference counting. -- -- The main difference with GNATCOLL.Refcount is that here, Element_Type is -- limited and constrained while in GNATCOLL.Refcount, Element_Type is not -- limited and unconstrained. with Ada.Finalization; with Ada.Unchecked_Deallocation; generic type Element_Type is limited private; -- The type to be boxed with function Refcount (Self : Element_Type) return Positive is <>; -- Return Self's reference count with procedure Set_Refcount (Self : in out Element_Type; Count : Positive); -- Set Self's reference count to Count with procedure Release (Self : in out Element_Type); -- Release all resources in Element_Type. This is called when the reference -- count drops to 0. package Gpr_Parser_Support.Boxes is type Element_Access is access all Element_Type; type Reference is private; -- Ref-counted reference to an Element_Type value No_Reference : constant Reference; -- Null reference (no element is referenced) function Create_Element return Reference; -- Allocate a new (uninitialized) element and return a reference to it procedure Update (Self : Reference; Callback : access procedure (Self : in out Element_Type)); -- Call Callback on the referenced Element_Type value function Internal_Access (Self : Reference) return Element_Access; -- Return an access to the referenced Element_Type value. This is unsafe, -- but can be a lot easier to use than the Update reference. As long as the -- returned Element_Access value does not outlive Self, all should be fine. private procedure Free is new Ada.Unchecked_Deallocation (Element_Type, Element_Access); type Reference is new Ada.Finalization.Controlled with record Internal : Element_Access; end record; overriding procedure Initialize (Self : in out Reference); overriding procedure Adjust (Self : in out Reference); overriding procedure Finalize (Self : in out Reference); No_Reference : constant Reference := (Ada.Finalization.Controlled with Internal => null); end Gpr_Parser_Support.Boxes;