我在通用函数中有一个数组,我想逐字节地迭代它。在下面的示例中,我使用
Wide_Wide_Character
,因此一个字符的长度为 4 个字节。对于给定的 3 个输入字符,我将需要迭代 12 个字节。我怎样才能实现这个目标?感谢您的宝贵时间。
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;
这是可以做到的。推荐的方法是引入一个嵌套循环,如下例所示,并将每个数组元素转换为存储数组。
不鼓励将数组
b
一次性转换为整个存储数组,因为如果索引类型是由非连续值表示的枚举类型,则数组可能不会连续存储在内存中。在这种情况下,数组可能会存储在带有“漏洞”的内存中,具体取决于编译器的实现。
测试.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;
输出
$ test
97
0
0
0
98
0
0
0
99
0
0
0