Ada 中泛型函数中的数组的按字节迭代

问题描述 投票:0回答:1

我在通用函数中有一个数组,我想逐字节地迭代它。在下面的示例中,我使用

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;
ada
1个回答
0
投票

这是可以做到的。推荐的方法是引入一个嵌套循环,如下例所示,并将每个数组元素转换为存储数组。

不鼓励将数组

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
© www.soinside.com 2019 - 2024. All rights reserved.