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