2011-10-27

Half-Constrained Arrays, Base Types, and Slicing

Array types can be unconstrained, half-constrained, or fully constrained. These are declared as:

type Name is array (Index_Type range <>) : Component_Type; -- Unconstrained.
type Name is array (Index_Type range Low .. <>) : Component_Type; -- Half constrained.
type Name is array (Index_Type[ range Low ..High]) : Component_Type; -- Constrained.

Note that the index subtype name is required. This is a requirement of range definitions in general, not of array type declarations.

A multi-dimensional array must have the same kind of constraint for all dimensions.

Type String is a half-constrained array type:

type String is array (General_Index_Value range 1 .. <>) : Character;

This can be considered shorthand for

type String'Base is array (General_Index_Value range <>) : Character;
subtype String is String'Base (General_Index_Value range 1 .. <>);

'Base can be applied to any array subtype to refer to the unconstrained base type.

Slicing a constrained or half-constrained array type yields a value of the base type. In the case of a half-constrained array, the result of slicing will slide when needed to meet the constraint of the half-constrained subtype. This applies, for example, in the case of passing a slice of a String to a subprogram that takes a String. The slice will slide to have a lower bound of 1.

It follows that libraries that manipulate half-constrained arrays need to carefully consider which parameters should be of the half-constrained subtype, and which of the unconstrained base type. An Index function into a String, for example, should take String'Base, so that the index into a slice is also the correct index into the original String.

No comments:

Post a Comment

Blog Archive