Ada Reference Manual (Ada 202x Draft 25)Legal Information
Contents   Index   References   Search   Previous   Next 

4.10 Image Attributes

1/5
An image of a value is a string representing the value in display form. The attributes Image, Wide_Image, and Wide_Wide_Image are available to produce the image of a value as a String, Wide_String, or Wide_Wide_String (respectively). User-defined images for a given type can be implemented by overriding the default implementation of the attribute Put_Image. 

Static Semantics

2/5
For every subtype S of a type T other than universal_real or universal_fixed, the following type-related operational attribute is defined:
3/5
S'Put_Image
S'Put_Image denotes a procedure with the following specification: 
3.1/5
procedure S'Put_Image
   (Buffer : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
    Arg    : in T);
3.2/5
The default implementation of S'Put_Image writes (using Wide_Wide_Put) an image of the value of Arg.
4/5
The Put_Image attribute may be specified for any specific type T either via an attribute_definition_clause or via an aspect_specification specifying the Put_Image aspect of the type.
5/5
The behavior of the default implementation of S'Put_Image depends on the class of T. For an elementary type, the implementation is equivalent to: 
6/5
procedure Scalar_Type'Put_Image
  (Buffer : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
   Arg    : in Scalar_Type) is
begin
   Buffer.Wide_Wide_Put (<described below>);
end Scalar_Type'Put_Image;
7/5
where the Wide_Wide_String value written out to the stream is defined as follows:
8/5
For an integer type, the image written out is the corresponding decimal literal, without underlines, leading zeros, exponent, or trailing spaces, but with a single leading character that is either a minus sign or a space.
9/5
For an enumeration type, the image written out is either the corresponding identifier in upper case or the corresponding character literal (including the two apostrophes); neither leading nor trailing spaces are included. For a nongraphic character (a value of a character type that has no enumeration literal associated with it), the value is a corresponding language-defined name in upper case (for example, the image of the nongraphic character identified as nul is "NUL" — the quotes are not part of the image).
10/5
For a floating point type, the image written out is a decimal real literal best approximating the value (rounded away from zero if halfway between) with a single leading character that is either a minus sign or a space, a single digit (that is nonzero unless the value is zero), a decimal point, S'Digits-1 (see 3.5.8) digits after the decimal point (but one if S'Digits is one), an upper case E, the sign of the exponent (either + or -), and two or more digits (with leading zeros if necessary) representing the exponent. If S'Signed_Zeros is True, then the leading character is a minus sign for a negatively signed zero.
11/5
For a fixed point type, the image written out is a decimal real literal best approximating the value (rounded away from zero if halfway between) with a single leading character that is either a minus sign or a space, one or more digits before the decimal point (with no redundant leading zeros), a decimal point, and S'Aft (see 3.5.10) digits after the decimal point.
12/5
For an access type (named or anonymous), the image written out depends on whether the value is null. If it is null, then the image is "NULL". Otherwise the image is a left parenthesis followed by "ACCESS", a space, and a sequence of graphic characters, other than space or right parenthesis, representing the location of the designated object, followed by a right parenthesis, as in "(ACCESS FF0012AC)".
13/5
For an array type T, the default implementation of T'Put_Image generates an image based on (named, not positional) array aggregate syntax (with '[' and ']' as the delimiters) using calls to the Put_Image procedures of the index type(s) and the element type to generate images for values of those types.
14/5
The case of a null array is handled specially, using ranges for index bounds and "<>" as a syntactic component-value placeholder.
15/5
The order in which components are written for a composite type is the same canonical order in which components of a composite type T are written out by the default implementation of T'Write. This is also the order that is used in determining the meaning of a positional aggregate of type T.
16/5
For a class-wide type, the default implementation of T'Put_Image generates an image based on qualified expression syntax. Wide_Wide_String'Write is called with Wide_Wide_Expanded_Name of Arg'Tag. Then S'Put_Image is called, where S is the specific type identified by Arg'Tag.
17/5
For a type extension, the default implementation of T'Put_Image depends on whether there exists a noninterface ancestor of T (other than T itself) for which the Put_Image aspect has been explicitly specified. If so, then T'Put_Image will generate an image based on extension aggregate syntax where the ancestor type of the extension aggregate is the nearest ancestor type whose Put_Image aspect has been specified.
18/5
If no such ancestor exists, then the default implementation of T'Put_Image is the same as described below for an untagged record type.
19/5
For an untagged record type, a specific tagged record type other than a type extension which meets the criteria described in the previous paragraph, or a protected type, the default implementation of T'Put_Image generates an image based on (named, not positional) record aggregate syntax (except that for a protected type, the initial left parenthesis is followed by "PROTECTED with "). Component names are displayed in upper case, following the rules for the image of an enumeration value. Component values are displayed via calls to the component type's Put_Image procedure.
20/5
The image written out for a record having no components (including any interface type) is "(NULL RECORD)". The image written out for a componentless protected type is "(PROTECTED NULL RECORD)". In the case of a protected type T, a call to the default implementation of T'Put_Image begins only one protected (read-only) action.
21/5
For an undiscriminated task type, the default implementation of T'Put_Image generates an image of the form "(TASK <task_id_image>)" where <task_id_image> is the result obtained by calling Task_Identification.Image with the id of the given task and then passing that String to Characters.Conversions.To_Wide_Wide_String.
22/5
For a discriminated task type, the default implementation of T'Put_Image also includes discriminant values, as in: 
23/5
"(TASK <task_id_image> with D1 =>  123, D2 =>  456)"
24/5
For every subtype S of a type T, the following attributes are defined:
25/5
S'Wide_Wide_Image

S'Wide_Wide_Image denotes a function with the following specification: 
25.1/5
function S'Wide_Wide_Image(Arg : S'Base)
  return Wide_Wide_String
25.2/5
S'Wide_Wide_Image calls S'Put_Image passing Arg (which will typically store a sequence of character values in a text buffer) and then returns the result of retrieving the contents of that buffer with Wide_Wide_Get. The lower bound of the result is one.
26/5
S'Wide_Image
S'Wide_Image denotes a function with the following specification: 
27/5
function S'Wide_Image(Arg : S'Base)
  return Wide_String
28/5
S'Wide_Image calls S'Put_Image passing Arg (which will typically store a sequence of character values in a text buffer) and then returns the result of retrieving the contents of that buffer with Wide_Get. The lower bound of the result is one.
29/5
S'Image
S'Image denotes a function with the following specification: 
30/5
function S'Image(Arg : S'Base)
  return String
31/5
S'Image calls S'Put_Image passing Arg (which will typically store a sequence of character values in a text buffer) and then returns the result of retrieving the contents of that buffer with Get. The lower bound of the result is one.
32/5
For a prefix X of a type T other than universal_real or universal_fixed, the following attributes are defined:
33/5
X'Wide_Wide_Image

X'Wide_Wide_Image denotes the result of calling function S'Wide_Wide_Image with Arg being X, where S is the nominal subtype of X.
34/5
X'Wide_Image
X'Wide_Image denotes the result of calling function S'Wide_Image with Arg being X, where S is the nominal subtype of X.
35/5
X'Image
X'Image denotes the result of calling function S'Image with Arg being X, where S is the nominal subtype of X. 

Implementation Permissions

36/5
An implementation may transform the image generated by the default implementation of S'Put_Image for a composite subtype S in the following ways:
37/5
If S is a composite subtype, the leading character of the image of a component value or index value is a space, and the immediately preceding character is an open parenthesis or bracket, then the space may be omitted. The same transformation is also permitted if the leading character of the component image is a space (in which case one of the two spaces may be omitted). 
38/5
If S is an array subtype, the low bound of the array in each dimension equals the low bound of the corresponding index subtype, and the array value is not a null array value, then positional array aggregate syntax may be used.
39/5
If S is an array subtype and the given value can be displayed using named_array_aggregate syntax where some discrete_choice_list identifies more than one index value by identifying a sequence of one or more ranges and values separated by vertical bars, then this image may be generated instead; this may involve the reordering of component values.
40/5
Similarly, if S is a record subtype (or a discriminated type) and the given value can be displayed using named component association syntax where the length of some component_choice_list is greater than one, then this image may be generated instead; this may involve the reordering of component values.
41/5
Additional spaces (Wide_Wide_Characters with position 32), and calls to the New_Line operation of a text buffer, may be inserted to improve readability of the generated image.
42/5
For each language-defined nonscalar type T, T'Put_Image may be specified.

Implementation Requirements

43/5
For each language-defined container type T (that is, each of the Vector, List, Map, Set, Tree, and Holder types defined in the various children of Ada.Containers), T'Put_Image shall be specified so that T'Image produces a result consistent with array aggregate syntax (using '[' and ']' as delimiters) as follows:
44/5
Vector images shall be consistent with the default image of an array type with the same index and component types.
45/5
Map images shall be consistent with named array aggregate syntax, using key value images in place of discrete choice names. For example, [Key1 => Value1, Key2 => Value2].
46/5
Set, List, and Holder images shall be consistent with positional array aggregate syntax. List elements shall occur in order within an image of a list. The image of an empty holder shall be [].
47/5
Tree images (and images of subtrees of trees) shall be consistent with positional array aggregate syntax. For example, [[1, 2], [111, 222, 333]].
48/5
For each language-defined nonscalar type T that has a primitive language-defined Image function whose profile is type conformant with that of T'Image (for example, Ada.Numerics.Float_Random.State has such an Image function), T'Put_Image shall be specified so that T'Image yields the same result as that Image function.

Implementation Advice

49/5
For each language-defined private type T, T'Image should generate an image that would be meaningful based only on the relevant public interfaces, as opposed to requiring knowledge of the implementation of the private type.

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe