A beginner's question, I'm afraid. I need to record the position (index) of a particular element in an array. Consider the following:
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
Ten : constant Positive := 10;
type ArrayIndex is new Positive range 1 .. Ten;
type MyRecord is record
firstItem : Integer;
secondItem : Integer;
end record;
TheRecords : array (1 .. Ten) of MyRecord;
indexOfElement50 : ArrayIndex := 1;
begin
-- set the values in TheRecords
for i in TheRecords'Range loop
TheRecords(i).firstItem := i * 10;
TheRecords(i).secondItem := i * 20;
end loop;
-- find which element of TheRecords has a
-- firstItem with a value of 50
for i in TheRecords'Range loop
if TheRecords(i).firstItem = 50 then
-- this next line is horrible: I should
-- not be required to do type casting
-- in a strongly-typed language.
indexOfElement50 := ArrayIndex(i);
exit;
end if;
end loop;
Put(ArrayIndex'image(indexOfElement50));
end Main;
Everything down to the comment "find which element of TheRecords has a firstItem with a value of 50" is just setting up the problem I have (in a much larger program, of course).
Although coming from a C and Python world, I have been trying to be religious about strong typing in Ada. So, I have defined "indexOfElement50" carefully, and I would like it to be the index to the element in TheRecords which has a firstItem of 50. The loop starting under the comment is the code which searches for that element. And finds it!
But then I have to cast i to be an ArrayIndex. And casting is so wrong in a strongly typed world. I have tried using indexOfElement50 as the loop parameter, but the compiler won't have any of that.
So, it seems that I am forced either to declare indexOfElement50 as an integer (which breaks the guideline of restricting ranges as much as possible), or to perform type casting (which is great in C, but which I shouldn't be doing in a strongly-typed language).
Or, which is more likely, I have missed something really obvious and this will be pointed out enthusiastically by the experts.
I’d be inclined to reverse the approach a little.
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
You really don’t need to have a constant named Ten
with value 10! What if you wanted to make it 12 later?
type MyRecord is record
firstItem : Integer;
secondItem : Integer;
end record;
We want an array of records, but let’s postpone the decision of how long it needs to be ...
type Record_Array is array (Positive range <>) of MyRecord;
... and define a test array, whose size happens to be 10 but could be anything.
TheRecords : Record_Array (1 .. 10);
A valid result (for this test program) can only be in TheRecords’Range
, but let’s add an out-of-range value to indicate ’not found’.
subtype Possible_Index is Natural range 0 .. TheRecords'Last;
indexOfElement50 : Possible_Index := 0; -- indicates 'not found'
OK!
begin
-- set the values in TheRecords
for i in TheRecords'Range loop
TheRecords(i).firstItem := i * 10;
TheRecords(i).secondItem := i * 20;
end loop;
-- find which element of TheRecords has a
-- firstItem with a value of 50
for i in TheRecords'Range loop
if TheRecords(i).firstItem = 50 then
indexOfElement50 := i;
exit;
end if;
end loop;
Put_Line (indexOfElement50'Image); -- legal in Ada2012
end Main;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With