Date:
Tue, 20 Oct 1998 06:41:32 +0100
|
> Reply-To: "W. Wesley Groleau x4923" <[log in to unmask]>
> 5. Use re-specification of derived types. This would also take some
> amount of re-tooling. Only you can say how much. This is a technique
> taught to me ten years ago when I was learning Ada 83, but I have since
> met many Ada programmers that don't know about it. (I don't recall
> ever actually using it myself.) Here is a partial example for
> four-octet integers. (I omitted the unchecked conversions, which
> should be obvious):
[..]
> -- the catch is that the compiler has to be smart enough to
> handle it, instead of stupidly implementing the conversion as an
> unchecked conversion. I do not know whether the ACVC tests this,
> and I have not yet had the time to test it on GNAT or Apex or
> ObjectAda. In fact, as you can see, I haven't even yet added the
> print statements to verify whether it works. But it SHOULD work.
> If anyone else has a chance to test it on any compiler, please
> share with me the test code and the results.
This is the technique we use with GNAT, using quite complex types,
successfully. The code below works (in its original context! a
Things.Value is a subtype of Interfaces.C.Int range -2**23 .. 2**23-1)
type Address is mod 2**18;
type Raw_Count is mod 2**6;
type Pad is array (Natural range <>) of Boolean;
pragma Pack (Pad);
type Control_Word_2 is record
Secondary_Address : Address;
Count : Raw_Count;
Padding_24_31 : Pad (24 .. 31);
end record;
package Control_Word_2_Conversions is
function Convert (Item : Things.Value) return Control_Word_2;
function Convert (Item : Control_Word_2) return Things.Value;
end Control_Word_2_Conversions;
package body Control_Word_2_Conversions is
type Control_Word_2_Rep_L is new Control_Word_2;
for Control_Word_2_Rep_L use record
Secondary_Address at 0 range 0 .. 17;
Count at 0 range 18 .. 23;
Padding_24_31 at 0 range 24 .. 31;
end record;
for Control_Word_2_Rep_L'Size use Things.Value'Size;
type Control_Word_2_Rep_B is new Control_Word_2;
for Control_Word_2_Rep_B use record
Secondary_Address at 0 range 14 .. 31;
Count at 0 range 8 .. 13;
Padding_24_31 at 0 range 0 .. 7;
end record;
for Control_Word_2_Rep_B'Size use Things.Value'Size;
function Convert (Item : Things.Value) return Control_Word_2 is
Result : Control_Word_2;
begin
if System.Default_Bit_Order = System.Low_Order_First then
declare
function Convert_To_Rep is
new Unchecked_Conversion (Things.Value,
Control_Word_2_Rep_L);
begin
Result := Control_Word_2 (Convert_To_Rep (Item));
end;
else
declare
function Convert_To_Rep is
new Unchecked_Conversion (Things.Value,
Control_Word_2_Rep_B);
begin
Result := Control_Word_2 (Convert_To_Rep (Item));
end;
end if;
return Result;
end Convert;
function Convert (Item : Control_Word_2) return Things.Value is
Result : Things.Value;
begin
if System.Default_Bit_Order = System.Low_Order_First then
declare
function Convert_From_Rep is
new Unchecked_Conversion (Control_Word_2_Rep_L,
Things.Value);
begin
Result := Convert_From_Rep (Control_Word_2_Rep_L (Item));
end;
else
declare
function Convert_From_Rep is
new Unchecked_Conversion (Control_Word_2_Rep_B,
Things.Value);
begin
Result := Convert_From_Rep (Control_Word_2_Rep_B (Item));
end;
end if;
return Result;
end Convert;
end Control_Word_2_Conversions;
|
|
|