comp.lang.ada
 help / color / mirror / Atom feed
From: joakimds@kth.se
Subject: Re: Calling a record type's methods (functions or procedure) when record is in an array
Date: Thu, 23 Jan 2020 07:00:15 -0800 (PST)
Date: 2020-01-23T07:00:15-08:00	[thread overview]
Message-ID: <e073de39-42bf-4571-aaaf-c7107d9f6962@googlegroups.com> (raw)
In-Reply-To: <6dbb0da9-8c68-435e-945d-d0e1eefeda4c@googlegroups.com>

> And now, you could change the type of the components to Point to Integer, remove the type-casts, and recompile the package Example **without having to recompile  dependent packages** because they are dependent only on the visible portion of the package.

Using Taft types introduced in Ada95 it is possible to add new components to a record type without recompilation of dependent packages. Here is an Ada 2005 example:

private with System.Storage_Elements;

package Cars is

   type Any_Car (<>) is limited private;
   --  This type is defined with unknown discriminant in order to make
   --  sure instances are properly initialized by allocator function.

   function Allocate_Car return Any_Car;
   --  The allocator function.

   type Car_Passenger_Count is range 0 .. 5;
   
   function Passenger_Count (Car : Any_Car) return Car_Passenger_Count;

   procedure Set_Passenger_Count
     (Car   : in out Any_Car;
      Value : Car_Passenger_Count);

private

   type Taft_Car;

   type Taft_Car_Ptr is access all Taft_Car;

   type Any_Car
     (Offset : System.Storage_Elements.Storage_Offset)
   is limited record
      Allocated_Memory : aliased
        System.Storage_Elements.Storage_Array (1 .. Offset);
      Reference : Taft_Car_Ptr;
   end record;

end Cars;



with System.Address_To_Access_Conversions;

package body Cars is

   type Taft_Car is record
      Passenger_Count : Car_Passenger_Count;
   end record;

   package Conversions is new System.Address_To_Access_Conversions
     (Object => Taft_Car);

   function Allocate_Car return Any_Car is
      Default : constant Any_Car
        := (Offset           => Taft_Car'Max_Size_In_Storage_Elements,
            Allocated_Memory => (others => 0),
            Reference        => null);
   begin
      return Car : Any_Car (Taft_Car'Max_Size_In_Storage_Elements) do
         declare
            First_Index : constant System.Storage_Elements.Storage_Offset
              := Car.Allocated_Memory'First;
         begin
            Car.Reference := Conversions.To_Pointer
              (Car.Allocated_Memory (First_Index)'Address).all'Access;
         end;
      end return;
   end Allocate_Car;

   function Passenger_Count (Car : Any_Car) return Car_Passenger_Count is
   begin
      return Car.Reference.Passenger_Count;
  end Passenger_Count;

   procedure Set_Passenger_Count
     (Car   : in out Any_Car;
      Value : Car_Passenger_Count) is
   begin
      Car.Reference.all.Passenger_Count := Value;
   end Set_Passenger_Count;
   
end Cars;


with Ada.Text_IO;

with Cars;
use  Cars;

procedure Main is
   Car : Cars.Any_Car := Cars.Allocate_Car;
begin
   Set_Passenger_Count (Car, 3);
   Ada.Text_IO.Put_Line (Passenger_Count (Car)'Image);
end Main;

Does somebody have a better implementation of Taft types where heap allocations are not used?

Perhaps this example is something to add to documentation on Ada on the internet like for example:
https://en.wikibooks.org/wiki/Ada_Programming/Tips

Anything wrong or could be improved with the implementation above?

Best regards,
Joakim


  parent reply	other threads:[~2020-01-23 15:00 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-17 23:30 Calling a record type's methods (functions or procedure) when record is in an array Mace Ayres
2020-01-18 12:31 ` Simon Wright
2020-01-18 18:02 ` Mace Ayres
2020-01-18 20:53   ` Simon Wright
2020-01-21 20:51   ` Shark8
2020-01-21 23:17     ` Jeffrey R. Carter
2020-01-23 15:00     ` joakimds [this message]
2020-01-23 15:02       ` joakimds
2020-01-23 16:51         ` Simon Wright
2020-01-24  9:47           ` joakimds
2020-01-23 20:15       ` Optikos
2020-01-19 15:06 ` Mace Ayres
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox