Advanced Array Aggregates

Note

These array aggregates are supported by

  • GNAT Community Edition 2020

  • GCC 11

Square brackets

In Ada 2022, you can use square brackets in array aggregates. Using square brackets simplifies writing both empty aggregates and single-element aggregates. Consider this:

pragma Ada_2022;
pragma Extensions_Allowed (On);

package Show_Square_Brackets is

   type Integer_Array is array (Positive range <>) of Integer;

   Old_Style_Empty : Integer_Array := (1 .. 0 => <>);
   New_Style_Empty : Integer_Array := [];

   Old_Style_One_Item : Integer_Array := (1 => 5);
   New_Style_One_Item : Integer_Array := [5];

end Show_Square_Brackets;

Short summary for parentheses and brackets

  • Record aggregates use parentheses

  • Container aggregates use square brackets

  • Array aggregates can use both square brackets and parentheses, but parentheses usage is obsolescent

Iterated Component Association

There is a new kind of component association:

Vector : Integer_Array := [for J in 1 .. 5 => J * 2];

This association starts with for keyword, just like a quantified expression. It declares an index parameter that you can use in the computation of a component.

Iterated component associations can nest and can be nested in another association (iterated or not). Here we use this to define a square matrix:

Matrix : array (1 .. 3, 1 .. 3) of Positive :=
 [for J in 1 .. 3 =>
   [for K in 1 .. 3 => J * 10 + K]];

Iterated component associations in this form provide both element indices and values, just like named component associations:

Data : Integer_Array (1 .. 5) :=
  [for J in 2 .. 3 => J, 5 => 5, others => 0];

Here Data contains (0, 2, 3, 0, 5), not (2, 3, 5, 0, 0).

Another form of iterated component association corresponds to a positional component association and provides just values, but no element indices:

Vector_2 : Integer_Array := [for X of Vector => X / 2];

You cannot mix these forms in a single aggregate.

It's interesting that such aggregates were originally proposed more than 25 years ago!

Complete code snippet:

pragma Ada_2022;
pragma Extensions_Allowed (On);  --  for square brackets

with Ada.Text_IO;

procedure Main is

   type Integer_Array is array (Positive range <>) of Integer;

   Old_Style_Empty : Integer_Array := (1 .. 0 => <>);
   New_Style_Empty : Integer_Array := [];

   Old_Style_One_Item : Integer_Array := (1 => 5);
   New_Style_One_Item : Integer_Array := [5];

   Vector : constant Integer_Array := [for J in 1 .. 5 => J * 2];

   Matrix : constant array (1 .. 3, 1 .. 3) of Positive :=
     [for J in 1 .. 3 =>
       [for K in 1 .. 3 => J * 10 + K]];

   Data : Integer_Array (1 .. 5) :=
     [for J in 2 .. 3 => J, 5 => 5, others => 0];

   Vector_2 : Integer_Array := [for X of Vector => X / 2];
begin
   Ada.Text_IO.Put_Line (Vector'Image);
   Ada.Text_IO.Put_Line (Matrix'Image);
   Ada.Text_IO.Put_Line (Data'Image);
   Ada.Text_IO.Put_Line (Vector_2'Image);
end Main;

References