0

I have read the following from wikibooks:

A pool access type handles accesses to objects which were created on some specific heap (or storage pool as it is called in Ada). A pointer of these types cannot point to a stack or library level (static) object or an object in a different storage pool. Therefore, conversion between pool access types is illegal. (Unchecked_Conversion may be used, but note that deallocation via an access object with a storage pool different from the one it was allocated with is erroneous.)

According the bold text, if the named access types belongs to the same memory pool then the conversion is legal?

I'm implementing a composite pattern, and I think I could improve the design if the composites return references to its concrete leaves and composites, avoiding the use of keyword "all" in the named access definition. I think I need memory pools to accomplish with it, but I think that it is an advanced feature and I haven't found enough documentation to be sure I can implement one by myself correctly.

I have been following the links shared in this post. Does anybody know other resources after ten years?

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Albatros23
  • 297
  • 2
  • 14
  • Why not a container, such as one of the `Multiway_Trees`? – trashgod Apr 24 '23 at 16:37
  • because my elements are limited – Albatros23 Apr 25 '23 at 06:14
  • 2
    Would [this](https://stackoverflow.com/a/64952885/40851) apply? – Simon Wright Apr 25 '23 at 07:43
  • 2
    @SimonWright wow, I've never thought I could extend an access type! (type Holder is new T_Access). Thank you, I think that can work properly, I'll update the question when I can try it :) – Albatros23 Apr 25 '23 at 15:26
  • @Albatros23 Technically speaking it ain't an extension of the access type. Just the derivation of a new access type using T_Access as a base. (consider 'type New_integer is new Integer') But there is more: doing it this way you also pull all the primitive operations to the place in which the new type is defined. It is not the same type as the original although it is exactly the same as the original: difference is in the name. – darkestkhan Apr 25 '23 at 17:22
  • @darkestkhan thank you for correcting me. What you mention about the primitive operations according the Simon's example is only possible if you derive the type publicly, righ? – Albatros23 Apr 26 '23 at 11:54
  • @SimonWright I'm a bit stupid, I think I can achieve what I intended with anonymous access types. If a client wants to get a concrete leaf or composite from the composite where they are contained, returning an anonymous access to the concrete leaf/composite would be enough. That way the client won't be able to free them, and the client will be able to modify them when needed – Albatros23 Apr 26 '23 at 12:22

1 Answers1

0

Hm, given the description, it seems like subpools would work well for this: have a subpooled-pool "for the composite type", where each component has a subpool.

But first, if there is any confusion as to what storage-pools are, or how to use them in Ada, it is an excellent exercise to implement one, and in the case of subpools its interface is given in System.Storage_Pools.Subpools.

package Example is
  Type Kpool is new System.Storage_Pools.Subpools.Root_Storage_Pool_With_Subpools
  with null record;


  overriding procedure Allocate
    (Pool                     : in out Kpool;
     Storage_Address          : out System.Address;
     Size_In_Storage_Elements : System.Storage_Elements.Storage_Count;
     Alignment                : System.Storage_Elements.Storage_Count) is null;

  overriding procedure Allocate_From_Subpool
    (Pool                     : in out Kpool;
     Storage_Address          : out System.Address;
     Size_In_Storage_Elements : System.Storage_Elements.Storage_Count;
     Alignment                : System.Storage_Elements.Storage_Count;
     Subpool                  : not null System.Storage_Pools.Subpools.Subpool_Handle) is null;

  overriding function Create_Subpool
    (Pool : in out Kpool)
     return not null System.Storage_Pools.Subpools.Subpool_Handle is
    (raise Program_Error);

  overriding procedure Deallocate
    (Pool                     : in out Kpool;
     Storage_Address          : System.Address;
     Size_In_Storage_Elements : System.Storage_Elements.Storage_Count;
     Alignment                : System.Storage_Elements.Storage_Count)
  is null;

  overriding procedure Deallocate_Subpool
    (Pool    : in out Kpool;
     Subpool : in out System.Storage_Pools.Subpools.Subpool_Handle)
  is null;
End Example;

----------
-- BODY --
----------
Package Body Example is
  -- Put implementations here.
End Example;

You can use Ada.Text_IO.Put_Line to "see" the data being passed, and from there figure out what you need to do with your data. (A good exercise is to make the pool hold an array of Storage_Element via discriminated record, and from there do the memory-management using those bytes.)

Shark8
  • 4,095
  • 1
  • 17
  • 31