Aspect Designated_Storage_Model (GNAT Reference Manual)

#### 17.3.3.2 Aspect Designated_Storage_Model ¶

A new aspect, Designated_Storage_Model, allows to specify the memory model for the objects pointed by an access type. Under this aspect, allocations and deallocations will come from the specified memory model instead of the standard ones. In addition, if write operations are needed for initialization, or if there is a copy of the target object from and to a standard memory area, the Copy_To and Copy_From functions will be called. It allows to encompass the capabilities of storage pools, e.g.:

    procedure Main is
       type Integer_Array is array (Integer range <>) of Integer;

       type Host_Array_Access is access all Integer_Array;
       type Device_Array_Access is access Integer_Array
          with Designated_Storage_Model => CUDA_Memory;

       procedure Free is new Unchecked_Deallocation
          (Host_Array_Type, Host_Array_Access);
       procedure Free is new Unchecked_Deallocation
          (Device_Array_Type, Device_Array_Access);

       Host_Array : Host_Array_Access := new Integer_Array (1 .. 10);

       Device_Array : Device_Array_Access := new Host_Array (1 .. 10);
       --  Calls CUDA_Storage_Model.Allocate to allocate the fat pointers and
       --  the bounds, then CUDA_Storage_Model.Copy_In to copy the values of the
       --  boundaries.
    begin
       Host_Array.all := (others => 0);

       Device_Array.all := Host_Array.all;
       --  Calls CUDA_Storage_Model.Copy_To to write to the device array from the
       --  native memory.

       Host_Array.all := Device_Array.all;
       --  Calls CUDA_Storage_Model.Copy_From to read from the device array and
       --  write to native memory.

       Free (Host_Array);

       Free (Device_Array);
       --  Calls CUDA_Storage_Model.Deallocate;
    end;

Taking `'Address` of an object with a specific memory model returns an object of the type of the address for that memory category, which may be different from System.Address.

When copying is performed between two specific memory models, the native memory is used as a temporary between the two. E.g.:

    type Foo_I is access Integer with Designated_Storage_Model => Foo;
    type Bar_I is access Integer with Designated_Storage_Model => Bar;

      X : Foo_I := new Integer;
      Y : Bar_I := new Integer;
    begin
      X.all := Y.all;

conceptually becomes:

      X : Foo_I := new Integer;
      T : Integer;
      Y : Bar_I := new Integer;
    begin
      T := Y.all;
      X.all := T;