We next discuss the implications of noncontiguous representations on assignment and comparison, indexing and case selection, and finally on iteration.
Note that no problem arises when such arrays are passed as parameters to subprograms since the index type is part of the array type and the same mapping will be used inside and outside the subprogram.
The user should be aware of the hidden storage costs involved: these costs are certainly preferable to prohibiting the use of types with noncontiguous representations for indexing and in case statements. If we consider character sets, for instance, the proportion of holes remains at an acceptable level.
This mechanism is illustrated by the following example. Consider the type MIX_CODE, for which a noncontiguous representation has been specified.
type MIX_CODE is (ADD, SUB, MUL, LDA, STA, STZ); for MIX_CODE use (ADD => 1, SUB => 2, MUL = > 3, LDA => 8, STA => 24, STZ => 33); |
A loop statement that iterates over the values of the MIX_CODE type can be written as follows:
for N in MIX_CODE loop DISPLAY(N); end loop; |
The compiler could produce object code equivalent to the following text (apart from typing rules):
PRESENT : constant array (1 .. 33) of BOOLEAN := (1 | 2 | 3 | 8 | 24 | 33 => TRUE, others => FALSE); for J in PRESENT'RANGE loop if PRESENT(J) then DISPLAY(J); end if; end loop; |
As illustrated above, the compilation involves a characteristic vector (PRESENT) which is used to generate the integer values corresponding to the enumeration type MIX_CODE. Thus we see that iterating over such types is possible, but involves extra cost.
Another technique is to use a representation vector that maps the ordinals into the enumeration values:
REPRESENTATION : constant array (0 .. 5) of INTEGER := (1,2,3,8,24,33); for J in REPRESENTATION'RANGE loop DISPLAY(REPRESENTATION(J)); end loop; |
Similar techniques are used to implement 'SUCC, 'PRED, 'POS and 'VAL.
type CHAR is (enumeration of all EBCDIC characters); type EBCDIC is new CHAR; -- same characters as CHAR for EBCDIC use (codes corresponding to EBCDIC characters); |
A user to whom the internal code is relevant (perhaps because he is performing input-output) will declare objects of type EBCDIC. For other uses, especially if such characters are to be used as indices, in case statements and in iterations, the user might prefer to use the type CHAR. Since no representation specification is given for this type, the translator will adopt a default representation that is convenient for indexing and iteration. Explicit conversion between the two types can be performed.
Note however that CHAR and EBCDIC will have their values in the same order, so the user cannot be relieved of all the problems associated with this wretched data type.