Packing enumerations


Ada enumerations let you enter a value for each member of the enumeration. This means you may create gaps, some of which could be really wide.

For example, the following enumeration has only 4 entries, but requires a 64 bit integer to hold all of its values:

type big (v1, v2, v3, v4);
for big use (v1 => 16#123#, v2 => 16#4444#,
             v3 => 16#FFFF_FFFF#, v4 => 16#1111_2222_3333#);

As mentioned in the enumeration representation (§13.4) the position remains the same whether or not a for ... use is specified. In other words, the internal representation can remain 0, 1, 2, 3 (the default values.)

A pragma pack on such a type can be used to force the storage of the enumeration to 0, 1, 2 and 3 instead of the for ... use specified values. (note that in a record, the enumeration can be packed in 2 bits instead of 64 bits.)


For the Pos(), Succ() and Pred() functions to continue to work without excessive processing, such a representation may always be necessary. A simple idea is to have an object that includes both numbers instead:

type enumeration is
  pos: integer;
  max: constant := ...;
  value: integer;
end record;

(detail: aada is to use the smallest integral type possible for each enumeration; may be with a minimum of integer to be compatible with other Ada compilers; we may use a pragma to determine the minimum and maximum sizes.)

pos is defined between 0 and max inclusive. value is the integer defined using the for ... use construct. If no for ... use was defined value = pos is always true.

Syndicate content