-- $Id: objinst.gnat,v 1.0 2003/06/11 12:07:00 dada Exp $
-- http://dada.perl.it/shootout/
-- Ada 95 code by C.C.
-- Annotated Ada Reference Manual ISO/IEC 8652:1995: http://www.ada-auth.org/
with Ada.Command_Line, Ada.Characters.Handling, Text_IO, Ada.Tags;
procedure ObjInst is -- 3.451
pragma Suppress (Discriminant_Check);
pragma Suppress (Access_Check);
package CH renames Ada.Characters.Handling;
use type Ada.Tags.Tag;
package Toggles is
type A_Rec is
tagged record -- 'tagged' allows fields to be added
Value : Boolean := True;
end record;
type B_Rec is new A_Rec with
record
Flip_Period : Positive := 1;
Count : Natural := 0;
end record;
type A_Recs_Family_Ptr is access all A_Rec'Class;
function Activate (X : A_Recs_Family_Ptr) return A_Recs_Family_Ptr;
pragma Inline (Activate);
end Toggles;
package body Toggles is
function Activate (X : A_Recs_Family_Ptr) return A_Recs_Family_Ptr is
pragma Suppress (Range_Check);
pragma Suppress (Tag_Check);
begin -- X is a ptr: no "in out" parms in a function
if X.all'Tag = A_Rec'Tag then -- A_Rec case
X.all.Value := not X.all.Value;
else
declare -- Make visible the 2 B_Rec fields
pragma Suppress (Tag_Check);
B : B_Rec renames B_Rec (X.all);
begin
B.Count := B.Count + 1;
if B.Count = B.Flip_Period then
B.Count := 0;
B.Value := not B.Value;
end if;
end;
end if;
return X;
end Activate;
end Toggles;
A : aliased Toggles.A_Rec; -- "aliased", since X'Access is used
B : aliased Toggles.B_Rec; -- "access all" above for aliased
N : Positive := 1;
Res : Boolean;
begin
begin
N := Positive'Value (Ada.Command_Line.Argument (1));
exception
when Constraint_Error => null;
end;
A := Toggles.A_Rec'(Value => True);
for K in 1 .. 5 loop
Res := Toggles.Activate (A'Access).Value;
Text_IO.Put_Line (CH.To_Lower (Boolean'Image (Res)));
end loop;
for Iter in 1 .. N loop
A := Toggles.A_Rec'(Value => True);
end loop;
Text_IO.New_Line;
B := Toggles.B_Rec'(Value => True, Flip_Period => 3, Count => 0);
for K in 1 .. 8 loop
Res := Toggles.Activate (B'Access).Value;
Text_IO.Put_Line (CH.To_Lower (Boolean'Image (Res)));
end loop;
for Iter in 1 .. N loop
B := Toggles.B_Rec'(Value => True, Flip_Period => 3, Count => 0);
end loop;
end ObjInst;