Generator/Exponential: Difference between revisions

add Ada
No edit summary
(add Ada)
Line 13:
'''See also'''
* [[wp:Generator (computer_science)|Generator]]
 
=={{header|Ada}}==
{{works with|Ada 2005}}
 
generator.ads:
<lang Ada>package Generator is
 
type Generator is tagged private;
procedure Reset (Gen : in out Generator);
function Get_Next (Gen : access Generator) return Natural;
 
type Generator_Function is access function (X : Natural) return Natural;
procedure Set_Generator_Function (Gen : in out Generator;
Func : Generator_Function);
 
procedure Skip (Gen : access Generator'Class; Count : Positive := 1);
 
private
 
function Identity (X : Natural) return Natural;
 
type Generator is tagged record
Last_Source : Natural := 0;
Last_Value : Natural := 0;
Gen_Func : Generator_Function := Identity'Access;
end record;
 
end Generator;</lang>
 
generator-filtered.ads:
<lang Ada>package Generator.Filtered is
 
type Filtered_Generator is new Generator with private;
procedure Reset (Gen : in out Filtered_Generator);
function Get_Next (Gen : access Filtered_Generator) return Natural;
 
procedure Set_Source (Gen : in out Filtered_Generator;
Source : access Generator);
procedure Set_Filter (Gen : in out Filtered_Generator;
Filter : access Generator);
 
private
 
type Filtered_Generator is new Generator with record
Last_Filter : Natural := 0;
Source, Filter : access Generator;
end record;
 
end Generator.Filtered;</lang>
 
generator.adb:
<lang Ada>package body Generator is
 
--------------
-- Identity --
--------------
 
function Identity (X : Natural) return Natural is
begin
return X;
end Identity;
 
----------
-- Skip --
----------
 
procedure Skip (Gen : access Generator'Class; Count : Positive := 1) is
Val : Natural;
pragma Unreferenced (Val);
begin
for I in 1 .. Count loop
Val := Gen.Get_Next;
end loop;
end Skip;
 
-----------
-- Reset --
-----------
 
procedure Reset (Gen : in out Generator) is
begin
Gen.Last_Source := 0;
Gen.Last_Value := 0;
end Reset;
 
--------------
-- Get_Next --
--------------
 
function Get_Next (Gen : access Generator) return Natural is
begin
Gen.Last_Source := Gen.Last_Source + 1;
Gen.Last_Value := Gen.Gen_Func (Gen.Last_Source);
return Gen.Last_Value;
end Get_Next;
 
----------------------------
-- Set_Generator_Function --
----------------------------
 
procedure Set_Generator_Function
(Gen : in out Generator;
Func : Generator_Function)
is
begin
if Func = null then
Gen.Gen_Func := Identity'Access;
else
Gen.Gen_Func := Func;
end if;
end Set_Generator_Function;
 
end Generator;</lang>
 
generator-filtered.adb:
<lang Ada>package body Generator.Filtered is
 
-----------
-- Reset --
-----------
 
procedure Reset (Gen : in out Filtered_Generator) is
begin
Reset (Generator (Gen));
Gen.Source.Reset;
Gen.Filter.Reset;
Gen.Last_Filter := 0;
end Reset;
 
--------------
-- Get_Next --
--------------
 
function Get_Next (Gen : access Filtered_Generator) return Natural is
Next_Source : Natural := Gen.Source.Get_Next;
Next_Filter : Natural := Gen.Last_Filter;
begin
loop
if Next_Source > Next_Filter then
Gen.Last_Filter := Gen.Filter.Get_Next;
Next_Filter := Gen.Last_Filter;
elsif Next_Source = Next_Filter then
Next_Source := Gen.Source.Get_Next;
else
return Next_Source;
end if;
end loop;
end Get_Next;
 
----------------
-- Set_Source --
----------------
 
procedure Set_Source
(Gen : in out Filtered_Generator;
Source : access Generator)
is
begin
Gen.Source := Source;
end Set_Source;
 
----------------
-- Set_Filter --
----------------
 
procedure Set_Filter
(Gen : in out Filtered_Generator;
Filter : access Generator)
is
begin
Gen.Filter := Filter;
end Set_Filter;
 
end Generator.Filtered;</lang>
 
example use:
<lang Ada>with Ada.Text_IO;
with Generator.Filtered;
 
procedure Generator_Test is
 
function Square (X : Natural) return Natural is
begin
return X * X;
end Square;
 
function Cube (X : Natural) return Natural is
begin
return X * X * X;
end Cube;
 
G1, G2 : aliased Generator.Generator;
F : aliased Generator.Filtered.Filtered_Generator;
 
begin
 
G1.Set_Generator_Function (Func => Square'Unrestricted_Access);
G2.Set_Generator_Function (Func => Cube'Unrestricted_Access);
 
F.Set_Source (G1'Unrestricted_Access);
F.Set_Filter (G2'Unrestricted_Access);
 
F.Skip (20);
 
for I in 1 .. 10 loop
Ada.Text_IO.Put ("I:" & Integer'Image (I));
Ada.Text_IO.Put (", F:" & Integer'Image (F.Get_Next));
Ada.Text_IO.New_Line;
end loop;
 
end Generator_Test;</lang>
 
output:
<pre>I: 1, F: 529
I: 2, F: 576
I: 3, F: 625
I: 4, F: 676
I: 5, F: 784
I: 6, F: 841
I: 7, F: 900
I: 8, F: 961
I: 9, F: 1024
I: 10, F: 1089</pre>
 
=={{header|C}}==
256

edits