Redefining the 'Image
attribute
In Ada 2022, you can redefine 'Image
attribute for your type,
though the syntax to do this has been changed several times. Let's see
how it works in GNAT Community 2021.
Note
Redefining attribute 'Image
is supported by
GNAT Community Edition 2021 (using
Text_Buffers
)GNAT Community Edition 2020 (using
Text_Output.Utils
)GCC 11 (using
Text_Output.Utils
)
In our example, let's redefine the 'Image
attribute for a
location in source code. To do this, we provide a new Put_Image
aspect for the type:
pragma Ada_2022; with Ada.Text_IO; with Ada.Strings.Text_Buffers; procedure Main is type Source_Location is record Line : Positive; Column : Positive; end record with Put_Image => My_Put_Image; procedure My_Put_Image (Output : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class; Value : Source_Location); procedure My_Put_Image (Output : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class; Value : Source_Location) is Line : constant String := Value.Line'Image; Column : constant String := Value.Column'Image; Result : constant String := Line (2 .. Line'Last) & ':' & Column (2 .. Column'Last); begin Output.Put (Result); end My_Put_Image; Line_10 : constant Source_Location := (Line => 10, Column => 1); begin Ada.Text_IO.Put_Line (Line_10'Image); end Main;
What's the Root_Buffer_Type?
Let's see how it's defined in the Ada.Strings.Text_Buffers
package.
type Root_Buffer_Type is abstract tagged limited private;
procedure Put
(Buffer : in out Root_Buffer_Type;
Item : in String) is abstract;
In addition to Put
, there are also Wide_Put
,
Wide_Wide_Put
, Put_UTF_8
, Wide_Put_UTF_16
. And
also New_Line
, Increase_Indent
, Decrease_Indent
.
Outdated draft implementation
GNAT Community Edition 2020 and GCC 11 both provide a draft
implementation that's incompatible with the Ada 2022 specification.
For those versions, My_Put_Image
looks like:
procedure My_Put_Image
(Sink : in out Ada.Strings.Text_Output.Sink'Class;
Value : Source_Location)
is
Line : constant String := Value.Line'Image;
Column : constant String := Value.Column'Image;
Result : constant String :=
Line (2 .. Line'Last) & ':' & Column (2 .. Column'Last);
begin
Ada.Strings.Text_Output.Utils.Put_UTF_8 (Sink, Result);
end My_Put_Image;