I have an array in a generic function where I want to iterate through it byte by byte. In the following example I am using Wide_Wide_Character
's, so a character is 4 bytes long. With 3 given input characters, I would have 12 bytes to iterate through. How can I achieve this? Thanks for your time.
with Ada.Text_IO;
procedure Test is
generic
type T is (<>);
type T_Index is range <>;
type T_Array is array (T_Index range <>) of T;
function A (b : T_Array) return Integer;
function A (b : T_Array) return Integer is
begin
-- how can I iterate here through each byte instead of "byte blocks"?
-- should be 12 bytes in this example (3 characters * 4 bytes)
-- can I map b to System.Storage_Elements.Storage_Array (without copying it)?
for I in 1 .. b'Length loop
Ada.Text_IO.Put_Line (b (T_Index (I))'Image);
end loop;
return 1;
end A;
function A1 is new A (Wide_Wide_Character, Positive, Wide_Wide_String);
unused : Integer := A1 ("abc");
begin
null;
end Test;
This can be done. The recommended way is to introduce a nested loop as shown in the example below and convert each array element to a storage array.
Converting the array b
to a storage array as a whole in one go is discouraged as an array may not be contiguously stored in memory if the index type is an enumeration type represented by non-contiguous values. In such case, the array may be stored in memory with "holes" depending on the compiler implementation.
test.adb
with Ada.Text_IO;
with Ada.Unchecked_Conversion;
with System.Storage_Elements;
procedure Test with SPARK_Mode is
generic
type T is (<>);
type T_Index is range <>;
type T_Array is array (T_Index range <>) of T;
procedure A (b : T_Array);
procedure A (b : T_Array) is
package SSE renames System.Storage_Elements;
use type SSE.Storage_Count;
Num_Storage_Elems : constant SSE.Storage_Count :=
T'Size / SSE.Storage_Element'Size;
subtype T_As_Storage_Array is SSE.Storage_Array (1 .. Num_Storage_Elems);
-- Conversion per array element.
function To_Storage_Array is new Ada.Unchecked_Conversion
(Source => T, Target => T_As_Storage_Array);
begin
for Elem of b loop
for Storage_Elem of To_Storage_Array (Elem) loop
Ada.Text_IO.Put_Line (Storage_Elem'Image);
end loop;
end loop;
end A;
procedure A1 is new A (Wide_Wide_Character, Positive, Wide_Wide_String);
begin
A1 ("abc");
end Test;
output
$ test
97
0
0
0
98
0
0
0
99
0
0
0