From 727e3c59346da4f91284b34b4c18f2e0ba155e53 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 9 Aug 2025 16:03:28 +0200 Subject: Initial commit --- ring_buffer/src/ring_buffer.adb | 94 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 ring_buffer/src/ring_buffer.adb (limited to 'ring_buffer/src') 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 @@ +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; -- cgit v1.2.3