Skip to content

Conversation

@liampwll
Copy link

This is a copy of Shared_Pointers except Set takes an anonymous function pointer instead of a value directly. This allows for the generic element type to be a limited type.

This is a copy of Shared_Pointers except Set takes an anonymous function
pointer instead of a value directly. This allows for the generic element
type to be a limited type.
@CLAassistant
Copy link

CLAassistant commented Nov 29, 2025

CLA assistant check
All committers have signed the CLA.

@liampwll
Copy link
Author

It might make sense to have Shared_Pointers wrap Limited_Shared_Pointers if GNAT can inline well enough to do so without any performance cost.

@Jicquel
Copy link
Collaborator

Jicquel commented Dec 4, 2025

Hi @liampwll, thanks for your contribution!

The current PR duplicates too much code to remain maintainable. Your suggestion of having Shared_Pointers built on top of Limited_Shared_Pointers would be a great improvement.

Could you also add tests to your PR, especially one that attempts to copy a limited version of the shared element?

As for the inlining performance issue, we can run benchmarks afterwards.

If that may help you, here is the main I used to test your MR:

with GNATCOLL.Refcount; use GNATCOLL.Refcount;
with Ada.Text_IO;       use Ada.Text_IO;

procedure Main is

   type Limited_Integer is limited record
      Value : Integer;
   end record;

   function Create return Limited_Integer is
   begin
      return (Value => 5000);
   end;

   package Integer_Pointers is new
     GNATCOLL.Refcount.Limited_Shared_Pointers
       (Element_Type => Limited_Integer);

   use Integer_Pointers;

   -- Declare shared pointer variables
   Ptr1, Ptr2, Ptr3 : Ref;

begin
   -- Set the shared pointer to contain the access type
   Set (Ptr1, Create'access);
   Put_Line
     ("After creating Ptr1, ref count: "
      & Natural'Image (Get_Refcount (Ptr1)));

   -- Copy the reference - this increments the reference count
   Ptr2 := Ptr1;
   Put_Line
     ("After creating Ptr2, ref count: "
      & Natural'Image (Get_Refcount (Ptr1)));

   -- Create another reference
   Ptr3 := Ptr1;
   Put_Line
     ("After creating Ptr3, ref count: "
      & Natural'Image (Get_Refcount (Ptr1)));

   -- Access and modify the string through different pointers
   Put_Line ("Original content: " & Integer'Image (Get (Ptr1).Value));

   -- Modify through Ptr2
   Get (Ptr2).Value := 2;

   declare
      B : Limited_Integer := Get (Ptr1);
      --  A : Limited_Integer := B; -- Uncommenting this line raises an error
   begin
      null;
   end;
   -- The change is visible through all pointers (they share the same data)
   Put_Line ("Content via Ptr1: " & Integer'Image (Get (Ptr1).Value));
   Put_Line ("Content via Ptr3: " & Integer'Image (Get (Ptr3).Value));

   -- Reset one pointer - decreases reference count
   Ptr1 := Null_Ref;
   Put_Line
     ("After resetting Ptr1, ref count via Ptr2: "
      & Natural'Image (Get_Refcount (Ptr2)));

   -- Reset another pointer
   Ptr2 := Null_Ref;
   Put_Line
     ("After resetting Ptr2, ref count via Ptr3: "
      & Natural'Image (Get_Refcount (Ptr3)));

   -- Modify through the last remaining pointer
   Get (Ptr3).Value := 3;
   Put_Line ("Final content: " & Integer'Image (Get (Ptr3).Value));
end Main;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants