blob: 500ec5ce6c1749479887c87c56f137b896e2e697 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
with Ada.Text_IO; use Ada.Text_IO;
procedure Ring_Buffer is
type Natural_Array is array (Natural range <>) of Integer;
type Ring_Buffer (Capacity : Natural) is record
Start_Index : Natural := 0; -- TODO: somehow make these 'mod Size'.
Cur_Index : Natural := 0;
Empty : Boolean := True;
-- TODO: the index type should be 'mod Size'.
-- TODO: 0 .. Capacity wastes 1 slot of space.
Buffer : Natural_Array (0 .. Capacity) := (others => 0);
end record;
function Size (RB : Ring_Buffer) return Natural is
begin
if RB.Empty then
return 0;
elsif RB.Cur_Index = RB.Start_Index then
return RB.Capacity;
else
return (RB.Cur_Index - RB.Start_Index) mod RB.Capacity;
end if;
end Size;
function Push (RB : in out Ring_Buffer; Value : Integer) return Boolean is
begin
if Size (RB) = RB.Capacity then
return False;
else
RB.Buffer (RB.Cur_Index) := Value;
RB.Cur_Index := (RB.Cur_Index + 1) mod RB.Capacity;
RB.Empty := False;
return True;
end if;
end Push;
procedure Push (RB : in out Ring_Buffer; Value : Integer) is
unused : Boolean := Push (RB, Value);
begin
return;
end Push;
function Pop (RB : in out Ring_Buffer; Value : out Integer) return Boolean is
begin
if Size (RB) = 0 then
return False;
else
Value := RB.Buffer (RB.Start_Index);
RB.Start_Index := (RB.Start_Index + 1) mod RB.Capacity;
if RB.Start_Index = RB.Cur_Index then
RB.Empty := True;
end if;
return True;
end if;
end Pop;
procedure Pop (RB : in out Ring_Buffer) is
Dummy : Integer;
unused : Boolean := Pop (RB, Dummy);
begin
return;
end Pop;
procedure Print (RB : Ring_Buffer) is
begin
Put ("[");
for I in 0 .. Size (RB) - 1 loop
Put (Integer'Image (RB.Buffer ((RB.Start_Index + I) mod RB.Capacity)));
end loop;
Put_Line ("]");
end Print;
Capacity : constant Natural := 5;
RB : Ring_Buffer (Capacity);
begin
Push (RB, 1);
Push (RB, 2);
Push (RB, 3);
Push (RB, 4);
Push (RB, 5);
-- Full!
Push (RB, 6);
Push (RB, 7);
-- Make some space.
Pop (RB);
Pop (RB);
-- Push more.
Push (RB, 8);
Push (RB, 9);
Print (RB);
end Ring_Buffer;
|