13.4 Enumeration Representation Clauses
Syntax
Name Resolution Rules
The
enumeration_aggregate
shall be written as a one-dimensional
array_aggregate,
for which the index subtype is the unconstrained subtype of the enumeration
type, and each component expression is expected to be of any integer
type.
Ramification: The “full coverage
rules” for
aggregates
applies. An
others is not allowed — there is no applicable
index constraint in this context.
Legality Rules
Ramification: As for all type-related
representation items, the
local_name
is required to denote a first subtype.
{
AI95-00287-01}
Each component of the
array_aggregate
shall be given by an
expression
rather than a <>. The
expressions
given in the
array_aggregate
shall be static, and shall specify distinct integer codes for each value
of the enumeration type; the associated integer codes shall satisfy the
predefined ordering relation of the type.
Reason: Each value of the enumeration
type has to be given an internal code, even if the first subtype of the
enumeration type is constrained to only a subrange (this is only possible
if the enumeration type is a derived type). This “full coverage”
requirement is important because one may refer to Enum'Base'First and
Enum'Base'Last, which need to have defined representations.
Static Semantics
An
enumeration_representation_clause
specifies the
coding aspect of representation.
The
coding consists of the
internal code for each enumeration literal,
that is, the integral value used internally to represent each literal.
Implementation Requirements
For nonboolean enumeration types, if the coding is
not specified for the type, then for each value of the type, the internal
code shall be equal to its position number.
Reason: This default representation is
already used by all known Ada compilers for nonboolean enumeration types.
Therefore, we make it a requirement so users can depend on it, rather
than feeling obliged to supply for every enumeration type an enumeration
representation clause that is equivalent to this default rule.
Discussion: For boolean types, it is
relatively common to use all ones for True, and all zeros for False,
since some hardware supports that directly. Of course, for a one-bit
Boolean object (like in a packed array), False is presumably zero and
True is presumably one (choosing the reverse would be extremely unfriendly!).
Implementation Advice
{
AI12-0444-1}
An implementation should support at least the internal codes in the range
System.Min_Int .. System.Max_Int. An implementation is not required to
support
enumeration_representation_clauses
for boolean types.
Ramification: The implementation may
support numbers outside the above range, such as numbers greater than
System.Max_Int. See AI83-00564.
Reason: The benefits of specifying the
internal coding of a boolean type do not outweigh the implementation
costs. Consider, for example, the implementation of the logical operators
on a packed array of booleans with strange internal codes. It's implementable,
but not worth it.
Static Semantics
{
AI12-0237-1}
For every discrete subtype S, the following attributes are defined:
S'Enum_Rep
{
AI12-0237-1}
S'Enum_Rep denotes a function with the following specification:
function S'Enum_Rep (Arg : S'Base) return universal_integer
This function returns the representation
value of the value of Arg, as a value of type
universal_integer.
The
representation value is
the internal code specified in an enumeration representation clause,
if any, for the type corresponding to the value of Arg, and otherwise
is the position number of the value.
S'Enum_Val
{
AI12-0237-1}
S'Enum_Val denotes a function with the following specification:
function S'Enum_Val (Arg : universal_integer) return S'Base
This function returns a value of the type
of S whose representation value equals the value of Arg. For the evaluation
of a call on S'Enum_Val, if there is no value in the base range of its
type with the given representation value, Constraint_Error is raised.
Reason: We define these on all discrete
types so that they can be used inside of a generic unit on a subtype
of a generic formal discrete type. They're not useful on integer types
(they have the same effect as S'Pos and S'Val).
Discussion:
Suppose the enumeration type in question is derived:
type T1 is (Red, Green, Blue);
subtype S1 is T1 range Red .. Green;
type S2 is new S1;
for S2 use (Red => 10, Green => 20, Blue => 30);
for I in S2'Base loop
... -- When I equals Blue, the internal code is 30.
end loop;
We considered allowing or requiring “for
S2'Base use ...” in cases like this, but it didn't seem
worth the trouble.
Examples
{
AI12-0312-1}
Examples of enumeration representation clauses:
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);
{
AI12-0312-1}
--
See 3.5.2.
for Roman_Digit
use ('I' => 1,
'V' => 5,
'X' => 10,
'L' => 50,
'C' => 100,
'D' => 500,
'M' => 1000);
Extensions to Ada 83
As in other similar contexts,
Ada 95 allows expressions of any integer type, not just expressions of
type
universal_integer, for the component expressions in the
enumeration_aggregate.
The preference rules for the predefined operators of
root_integer
eliminate any ambiguity.
For portability, we now require that the default
coding for an enumeration type be the “obvious” coding using
position numbers. This is satisfied by all known implementations.
Wording Changes from Ada 95
{
8652/0009}
{
AI95-00137-01}
Corrigendum: Updated to reflect that we no longer have something
called
representation_clause.
Extensions to Ada 2012
{
AI12-0237-1}
Attributes Enum_Rep and Enum_Val are new.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe