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
next prev 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