What is the idiomatic way of specifying a range with an invalid value? [closed]
Solution 1:
I like to use a variant record in situations like this. It allows you to specify that an ID only exists if the Valid discriminant is set to True. It also allows Ada's strong type checking to enforce that invariant (I.E. if you try to access the ID of an invalid core, the code will raise an exception).
with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is
type Core_Identifier is new Positive range 1 .. 10;
type Core (Valid : Boolean := False) is record
case Valid is
when True => ID : Core_Identifier := 1;
when False => null;
end case;
end record;
Invalid_Core : constant Core := (Valid => False);
-- Constructing function
function Make_Core(ID : Core_Identifier) return Core
is (Valid => True, ID => ID);
-- Various initialization methods
Core_1 : Core := Invalid_Core;
Core_2 : Core := (Valid => True, ID => 6);
Core_3 : Core := Make_Core(9);
Core_4 : Core := (Valid => False);
begin
Put_Line("Hello, world!");
if not Core_1.Valid then
Put_Line("Core 1 invalid");
else
Put_Line("Core 1 ID:" & Core_1.ID'Image);
end if;
if not Core_2.Valid then
Put_Line("Core 2 invalid");
else
Put_Line("Core 2 ID:" & Core_2.ID'Image);
end if;
if not Core_3.Valid then
Put_Line("Core 3 invalid");
else
Put_Line("Core 3 ID:" & Core_3.ID'Image);
end if;
if not Core_4.Valid then
Put_Line("Core 4 invalid");
else
Put_Line("Core 4 ID:" & Core_4.ID'Image);
end if;
end Hello;