Spec-Zone.ru › Ada 2022
Справочник по Ada (Ada 2022)

4.3.3 Агрегаты массивов

В array_aggregate, значение задается для каждого компонента массива, либо позиционно, либо по индексу. Для positional_array_aggregate, компоненты задаются в порядке возрастания индексов, при этом ключевое слово others, если оно используется, представляет все оставшиеся компоненты. Для named_array_aggregate, компоненты идентифицируются значениями, охватываемыми discrete_choices.

Синтаксис

array_aggregate ::=
positional_array_aggregate | null_array_aggregate | named_array_aggregate
positional_array_aggregate ::=
(expression, expression {, expression})
| (expression {, expression}, others => expression)
| (expression {, expression}, others => <>)
| '[' expression {, expression}[, others => expression] ']'
| '[' expression {, expression}, others => <> ']'
null_array_aggregate ::= '[' ']'
named_array_aggregate ::=
(array_component_association_list)
| '[' array_component_association_list ']'
array_component_association_list ::=
array_component_association {, array_component_association}
array_component_association ::=
discrete_choice_list => expression
| discrete_choice_list => <>
| iterated_component_association
iterated_component_association ::=
for defining_identifier in discrete_choice_list => expression
| for iterator_specification => expression
Многомерный array_aggregate — это такой, который записывается как n уровней вложенных array_aggregate (или на нижнем уровне эквивалентные string_literal). В многомерном случае (n >= 2) array_aggregate (или эквивалентные string_literals) на n–1 нижних уровнях называются под-агрегатами окружающего n-мерного array_aggregate. expressionы нижнего уровня под-агрегатов (или самого array_aggregate при одномерном случае) называются выражениями компонентов массива окружающего n-мерного array_aggregate.
Идентификатор defining_identifier в iterated_component_association объявляет параметр индекса, объект соответствующего типа индекса.

Правила разрешения имен

Ожидаемый тип для array_aggregate (который не является под-агрегатом) должен быть единственным типом массива. Тип компонента этого массива является ожидаемым типом для каждого выражения компонента массива в array_aggregate.
Ожидаемый тип для каждого discrete_choice в любом discrete_choice_list в named_array_aggregate — тип соответствующего индекса. Соответствующий индекс для array_aggregate, который не является под-агрегатом, — это первый индекс его типа. Для (n–m)-мерного под-агрегата внутри array_aggregate n-мерного типа соответствующий индекс — индекс в позиции m+1.

Правила легальности

array_aggregate n-мерного массива должен быть записан как n-мерный array_aggregate или как null_array_aggregate.
Выбор others разрешен для array_aggregate только если применима соответствующая ограничение индексов к array_aggregate. Соответствующее ограничение индексов — это ограничение, предоставляемое определёнными контекстами, которые могут быть использованы для определения границ значения массива, задаваемого array_aggregate. Каждый из следующих контекстов (и никакой другой) определяет соответствующее ограничение индексов:
  • Для explicit_actual_parameter, explicit_generic_actual_parameter, выражения оператора return, выражения возврата функции, выражения инициализации в object_declaration или default_expression (для параметра или компонента), когда номинальный подтип соответствующего формального параметра, формального параметра обобщения, объекта возврата функции, объекта возврата функции выражения, объекта или компонента является ограниченным типом массива, соответствующим ограничением индексов является ограничение подтипа;
  • Для выражения оператора assignment_statement, где имя обозначает переменную массива, соответствующим ограничением индексов является ограничение переменной массива;
  • Для операнда qualified_expression, где subtype_mark обозначает ограниченный подтип массива, соответствующим ограничением индексов является ограничение подтипа;
  • Для выражения компонента в aggregate, если номинальный подтип компонента является ограниченным типом массива, соответствующим ограничением индексов является ограничение подтипа;
  • Для базового выражения delta_aggregate, если номинальный подтип delta_aggregate является ограниченным типом массива, соответствующим ограничением индексов является ограничение подтипа;
  • Для скобочного выражения, соответствующим ограничением индексов является то, если оно есть, определенное для выражения;
  • Для conditional_expression (см. 4.5.7), соответствующим ограничением индексов для каждого зависимого выражения является то, если оно есть, определённое для conditional_expression;
END_OF_DOCUMENT_MARKER
  • Для declare_expression (см. 4.5.9), применимое ограничение индекса для body_expression — это, если таковое определено, ограничение индекса для declare_expression.
Применимое ограничение индекса применяется к array_aggregate, который появляется в таком контексте, а также к любым вложенным агрегатам. В случае explicit_actual_parameter (или default_expression) для вызова генерического формального подпрограммы, применимое ограничение индекса не определено.
Список discrete_choice_list array_component_association (включая iterated_component_association) допускает discrete_choice, который является нестатическим choice_expression или является subtype_indication или range, определяющим нестатический или нулевой диапазон, только если это единственный discrete_choice его discrete_choice_list, и либо существует только одна array_component_association в окружающем списке array_component_association_list, либо окружающий агрегат aggregate является array_delta_aggregate, а не array_aggregate.
Все или ни одной из array_component_associations списка array_component_association_list должны быть iterated_component_associations с iterator_specification.
В named_array_aggregate, где все discrete_choice являются статическими, запрещено, чтобы два discrete_choice покрывали одно и то же значение (см. 3.8.1); если нет выбора others, то discrete_choice вместе должны точно охватывать непрерывную последовательность значений соответствующего типа индекса.
Подмножество многомерного array_aggregate заданного типа массива может быть string_literal только если тип компонента типа массива является типом символов; каждый символ такого string_literal должен соответствовать defining_character_literal типа компонента.

Статическая семантика

Подмножество, которое является string_literal, эквивалентно positional_array_aggregate той же длины, где каждый expression является character_literal для соответствующего символа string_literal.
Тип подтипа (и номинального подтипа) параметра индекса — соответствующий подтип индекса.

Динамическая семантика

Для array_aggregate, который содержит только array_component_associations, которые являются iterated_component_associations с iterator_specifications, вычисление выполняется в два этапа:
1.
Каждый iterator_specification обрабатывается (в произвольном порядке) и выполняется итерация только для определения максимального количества значений, производимых итерацией; все эти количества комбинируются для определения общей длины массива, а в конечном итоге — границ массива (определены ниже);
2.
Выполняется вторая итерация для каждого iterator_specification в заданном порядке в aggregate, и для каждого условно производимого значения итерации (см. 5.5 и 5.5.2) соответствующее expression вычисляется, его значение преобразуется в подтип компонента типа массива и используется для определения значения следующего компонента массива, начиная с нижней границы и последовательно приближаясь к верхней границе. Проверяется, что результат второй итерации приводит к длине массива, не превышающей максимальную, определенную первой итерацией; если эта проверка завершается неудачно, возникает ошибка Constraint_Error.
Вычисление любого другого array_aggregate заданного типа массива выполняется в два этапа:
1.
Все discrete_choice этого агрегата и его подмножеств вычисляются в произвольном порядке и преобразуются в соответствующий тип индекса;
2.
Выражения компонентов массива агрегата вычисляются в произвольном порядке, и их значения преобразуются в подтип компонента типа массива; выражение компонента массива вычисляется один раз для каждого связанного компонента.
Каждое expression в array_component_association определяет значение для соответствующего компонента(ов). Для array_component_association с <>, связанные компоненты инициализируются значением Default_Component_Value типа массива, если этот аспект был указан для типа массива; в противном случае они инициализируются по умолчанию, как для отдельного объекта подтипа компонента (см. 3.3.1).
Во время вычисления expression iterated_component_association со списком discrete_choice_list значение соответствующего параметра индекса — значение соответствующего индекса соответствующего компонента массива. Во время вычисления expression iterated_component_association с iterator_specification значение параметра цикла iterator_specification — значение, произведённое итерацией (как описано в 5.5.2).
Границы диапазона индексов array_aggregate (включая подмножество) определяются следующим образом:
  • Для array_aggregate с выбором others границы — это границы соответствующего диапазона индексов из применимого ограничения индекса;
  • Для positional_array_aggregate (или эквивалентного string_literal) без выбора others нижняя граница — это нижняя граница соответствующего диапазона индексов в применимом ограничении индекса, если определено, или нижняя граница соответствующего подтипа индекса, если не определено; в любом случае верхняя граница определяется по нижней границе и числу expressions (или длины string_literal);
  • Для null_array_aggregate границы для каждой размерности определяются как для positional_array_aggregate без выбора others, не имеющего выражений для каждой размерности;
  • Для named_array_aggregate, содержащего только iterated_component_association с iterator_specification, нижняя граница определяется так же, как для positional_array_aggregate без выбора others, а верхняя граница определяется из нижней границы и общего количества значений, производимых второй серией итераций;
  • Для любого другого named_array_aggregate без выбора others границы определяются наименьшим и наибольшим значениями индексов, охватываемыми любым discrete_choice_list.
Для array_aggregate проверяется, что диапазон индексов, определённый его границами, совместим с соответствующим подтипом индекса.
Для array_aggregate с выбором others проверяется, что ни одно выражение expression или <> не указано для значения индекса вне границ, определяемых применимым ограничением индекса.
Для многомерного array_aggregate проверяется, что все под-агрегаты, соответствующие одному и тому же индексу, имеют одинаковые границы.
Исключение Constraint_Error генерируется, если любая из вышеперечисленных проверок завершается неудачно.

Разрешения реализации

При оценке iterated_component_association для array_aggregate, содержащего только iterated_component_association с iterator_specification, первый шаг оценки iterated_component_association может быть пропущен, если реализация может определить максимальное количество значений другими средствами.
ПРИМЕЧАНИЕ 1 В array_aggregate, ограниченном скобками, позиционная нотация может использоваться только с двумя или более expressions; одно expression в скобках интерпретируется как выражение в скобках. array_aggregate, ограниченный квадратными скобками, может использоваться для указания массива с одним компонентом.
ПРИМЕЧАНИЕ 2 Параметр индекса — это постоянный объект (см. 3.3).

Примеры

Примеры агрегатов массивов с позиционными ассоциациями:
(7, 9, 5, 1, 3, 2, 4, 8, 6, 0)
Table'(5, 8, 4, 1, others => 0) -- см. 3.6
Примеры агрегатов массивов с именованными ассоциациями:
(1 .. 5 => (1 .. 8 => 0.0)) -- двумерный
[1 .. N => new Cell] -- N новых ячеек, в частности для N = 0
Table'(2 | 4 | 10 => 1, others => 0)
Schedule'(Mon .. Fri => True, others => False) -- см. 3.6
Schedule'[Wed | Sun => False, others => True]
Vector'(1 => 2.5) -- однокомпонентный вектор
Примеры двумерных агрегатов массивов:
-- Три агрегата для одного и того же значения подтипа Matrix(1..2,1..3) (см. 3.6):
((1.1, 1.2, 1.3), (2.1, 2.2, 2.3))
(1 => [1.1, 1.2, 1.3], 2 => [2.1, 2.2, 2.3])
[1 => (1 => 1.1, 2 => 1.2, 3 => 1.3),
2 => (1 => 2.1, 2 => 2.2, 3 => 2.3)]
Примеры агрегатов в качестве начальных значений:
A : Table := (7, 9, 5, 1, 3, 2, 4, 8, 6, 0); -- A(1)=7, A(10)=0
B : Table := (2 | 4 | 10 => 1, others => 0); -- B(1)=0, B(10)=1
C : constant Matrix := (1 .. 5 => (1 .. 8 => 0.0));
-- C'Last(1)=5, C'Last(2)=8
D : Bit_Vector(M .. N) := (M .. N => True); -- см. 3.6
E : Bit_Vector(M .. N) := (others => True);
F : String(1 .. 1) := (1 => 'F'); -- агрегат из одного компонента: то же самое, что и "F"
G : constant Matrix :=
(for I in 1 .. 4 =>
(for J in 1 .. 4 =>
(if I=J then 1.0 else 0.0))); -- Единичная матрица
Empty_Matrix : constant Matrix := []; -- Матрица без элементов
Пример агрегата массива с необязательным выбором others и с применимым ограничением индекса, предоставляемым окружающим агрегатом записи:
Buffer'(Size => 50, Pos => 1, Value => ('x', others => <>)) -- см. 3.7


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API