Агрегат — это базовая операция, которая объединяет значения компонент в составное значение именуемого или индексируемого типа.
агрегат ::= (сопоставление-компонент {, сопоставление-компонент}) сопоставление-компонент ::= [выбор { | выбор} = > ] выражение
Каждое сопоставление компонент связывает выражение с компонентами. Сопоставление компонент называется именованным, если компоненты явно определены выборами, и позиционным в противном случае. При позиционном сопоставлении каждой отдельно взятой компоненте неявно соответствует некоторая позиция: именуемым компонентам — в порядке следования их описаний, индексируемым компонентам — по возрастанию индекса.
Именованные сопоставления могут стоять в произвольном порядке (исключая выбор others), но если в агрегате одновременно используются позиционные и именованные сопоставления, то первыми должны стоять позиционные сопоставления, каждое на своем месте. Следовательно, за именованными сопоставлениями в агрегате могут следовать только именованные сопоставления. В агрегатах, содержащих единственное сопоставление, должно всегда использоваться именованное сопоставление. Правила для сопоставления компонент агрегатов именуемого типа и агрегатов индексируемого типа определены в разд. 4.3.1 и 4.3.2.
Синтаксис выборов сопоставления компонент совпадает с синтаксисом разделов вариантов (см. 3.7.3). Выбор, являющийся простым именем компоненты, допустим только в агрегатах именуемого типа. Выбор, являющийся выражением или дискретным диапазоном, допустим только в агрегатах индексируемого типа; выбор, являющийся простым выражением, задает значение индекса; дискретный диапазон задает диапазон значений индекса. Выбор others допустим только в последнем сопоставлении компонент в качестве единственного выбора и определяет все оставшиеся компоненты, если они есть.
Каждая компонента значения, определяемого агрегатом, должна встретиться в агрегате один и только один раз. Следовательно, каждый агрегат должен быть полным, и не допускается, чтобы данная компонента была задана более чем одним выбором.
Тип агрегата должен быть определим исключительно из контекста, в котором встречается агрегат, без учета самого агрегата, используя только тот факт, что его тип должен быть составным и нелимитированным. Тип агрегата в свою очередь определяет требуемый тип для каждой его компоненты.
Примечание. Приведенное выше правило означает, что для определения типа агрегата не может быть использована информация, которую несет в себе агрегат. В частности, это определение не может использовать тип выражения в сопоставлении компонент, формы или типы выборов. Агрегат с одной компонентой всегда можно отличить от выражения, заключенного в скобки, благодаря обязательному именованию компоненты такого агрегата.
Ссылки: агрегат записи 4.3.1, агрегат массива 4.3.2, базовая операция типа 3.3.3, выбор 3.7.3, выражение 4.4, дискретный диапазон 3.6, именуемый тип 3.7, индекс 3.6, индексируемый тип 3.6, компонента 3.3, лимитируемый тип 7.4.4, первичное 4.4, простое выражение 4.4, простое имя 4.1, раздел вариантов 3.7.3, составное значение 3.3, составной тип 3.3, тип 3.3.
4.3.1. АГРЕГАТЫ ЗАПИСЕЙ
Для агрегата именуемого типа (агрегата записи) имена компонент, заданные выборами, должны обозначать компоненты (включая дискриминанты) именуемого типа. Выбор others в агрегатах записей должен представлять хотя бы одну компоненту. Сопоставление компонент с выбором others или более чем с одним выбором допускается только тогда, когда представленные компоненты имеют один и тот же тип. Выражение в сопоставлении компонент должно иметь тип соответствующей компоненты записи.
Значение, определяющее дискриминант, должно быть задано статическим выражением (заметим, что это значение определяет, какие из зависимых компонент должны присутствовать в значении записи).
При вычислении агрегатов записи порядок вычисления выражений в сопоставлениях компонент в языке не определен. Выражение в именованном сопоставлении вычисляется один раз для каждой сопоставленной компоненты. Производится проверка на принадлежность значения каждой подкомпоненты агрегата подтипу этой подкомпоненты. При нарушении проверки возбуждается исключение CONSTRAINT_ERROR.
Пример агрегата записи с позиционным сопоставлением:
(4, JULY, 1776) -- см. 3.7 Примеры агрегатов записи с именованными сопоставлениями:(DAY => 4, MONTH => JULY, YEAR => 1776)(MONTH => JULY, DAY => 4, YEAR => 1776)(DISK, CLOSED, TRACK => 5, CYLINDER => 12) -— см. 3.7.3 (UNIT => DISK, STATUS => CLOSED, CYLINDER => 9, TRACK => 1)Примеры сопоставления компонент с несколькими выборами:(VALUE => 0, SUCCIPRED => new CELL'IO, null, null)) —- см. 3.8.1—- Генератор вычисляется дважды: SUCC и PRED обозначают разные ячейки
Примечание: В агрегате с позиционными сопоставлениями первыми идут значения дискриминантов, так как раздел дискриминантов идет первым в описании именуемого типа; они должны быть в том же порядке, что и в разделе дискриминантов.
Ссылки: агрегат 4.3, в некотором порядке 1.6, возбуждение исключения 11, выбор 3.7.3, выражение 4.4, вычисление 4.5, генератор 4.8, дискриминант 3.3, зависит от дискриминанта 3.7.1, именуемый тип 3.7, имя компоненты 3.7, исключение CONSTRAINT_ERROR 11.1, компонента записи 3.7, ограничение 3.3, подкомпонента 3.3, подтип 3.3.2, программа 10, раздел вариантов 3.7.3, раздел дискриминантов 3.7.1, сопоставление компонент 4.3, статическое выражение 4.9, тип 3.3, удовлетворять 3.3.
4.3.2. АГРЕГАТЫ МАССИВОВ
Если тип агрегата — одномерный индексируемый тип, то каждый выбор должен задавать значения индекса, а выражение в каждом сопоставлении компонент должно иметь тип соответствующей компоненты.
Если тип агрегата — многомерный индексируемый тип, то n-мерный агрегат записывается как одномерный, в котором выражения, задающие сопоставления компонент, сами записываются как (n - 1)-мерный агрегат, называемый подагрегатом; подтип индекса одномерного агрегата задается первой позицией индекса индексируемого типа. То же правило используется для следующей позиции индекса при записи подагрегатов, если они опять многомерные. В многомерном агрегате допустимо использование строкового литерала в качестве одномерного массива символьного типа. В дальнейшем связанные с агрегатами массивов правила формулируются в терминах одномерных агрегатов.
За исключением последнего сопоставления компонент с единственным выбором others, остальные сопоставления (если они есть) агрегата массива должны быть либо все позиционными, либо все именованными. Для агрегата массива, имеющего одно именованное сопоставление компонент с одним выбором, допускается задание только такого выбора, который не является статическим или является пустым диапазоном. Выбор others является статическим, если статическим является соответствующее ограничение индекса.
Границы агрегата массива, имеющего выбор others, определяются соответствующим ограничением индекса. Использование выбора others допускается только тогда, когда агрегат находится в одном из следующих контекстов (контекст определяет соответствующее ограничение индекса):
а) Агрегат — это фактический параметр, фактический параметр настройки, выражение, являющееся результатом функции, или выражение, которое следует за составным ограничителем присваивания, и подтип соответствующего формального параметра, формального параметра настройки, результат функции или объекта — ограниченный индексируемый подтип.
Для агрегата, помещенного в такой контекст и содержащего сопоставление с выбором others, другие именованные сопоставления допускаются только в случае фактического параметра (не являющегося фактическим параметром настройки) или результата функции. Если' агрегат — многомерный массив, то это ограничение распространяется и на все подагрегаты.
б) Агрегат — это операнд квалифицированного выражения, обозначение типа которого указывает ограниченный индексируемый подтип.
в) Агрегат — это выражение в сопоставлении компонент другого агрегата индексируемого или именуемого типа, и если этот объемлющий агрегат — многомерный агрегат индексируемого типа, то сам он заключен в один из этих трех видов контекста.
Границы агрегата массива без выбора otners определяются следующим образом. Для агрегата с именованными сопоставлениями границы определяются наименьшим и наибольшим из заданных выборов. Нижняя граница позиционного агрегата определяется соответствующим ограничением индекса, если агрегат помещен в один из контекстов а), б) или в); в противном случае нижняя граница задается как S'FIRST, где S — подтип индекса; в обоих случаях верхняя граница определяется числом компонент.
Вычисление агрегата массива, не являющегося подагрегатом, производится в два шага. На первом шаге вычисляются выборы данного агрегата и его подагрегатов, если они есть, в порядке, не определенном в языке. На втором — вычисляются выражения в сопоставлениях компонент в порядке, также не определенном в языке. Выражение в именованном сопоставлении вычисляется один раз для каждой сопоставляемой компоненты. Вычисление подагрегатов состоит из этого второго шага (первый шаг пропускается, так как выборы уже были вычислены).
При вычислении непустого агрегата массива производится проверка того, что значения задаваемых выборами индексов принадлежат соответствующему подтипу индекса, а также того, что значение каждой подкомпоненты агрегата принадлежит подтипу этой подкомпоненты. Для n-мерного агрегата производится проверка того, что все (n - 1)-мерные подагрегаты имеют одинаковые границы. Если хотя бы одна из этих проверок дает отрицательный результат, возбуждается исключение CONSTRAINT_ERROR.
Примечание. Допустимыми константами агрегата массива с выбором others являются те, в которых границы такого агрегата всегда известны из контекста.
Примеры агрегатов массивов с позиционными сопоставлениями:
(7, 9, 5, 1, 3, 2, 4, 8, 6, 0) ТАВLЕ'(5, 8, 4,1, others => 0) -- см. 3.6
Примеры агрегатов массивов с именованными сопоставлениями:
(1 .. 5 => (1 .. 8 => 0.0)) —- двумерный (1 .. N => new CELL) -— N новых ячеек, в частности для N = 0ТАВLЕ'(2 | 4 | 10 => 1, others => 0) SСHEDULE'(MON .. FRI => TRUE, others => FALSE) --см. 3.6 SCHEDULE'(WED | SUN => FALSE, others => TRUE )
Поимеоы агрегатов двумерных массивов:
-- три агрегата с одним значением типа MATRIX, см. 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))
Примеры агрегатов в качестве значений инициализации:
А : TABLE := (7, 9, 5, 1, 3, 2, 4, 8, 6, 0); -- А(1)=7, А(10)=0В : TABLE := ТАВLЕ'(2 | 4 | 10 => 1, others => 0); -- В(1)=0, В(10)=1С : constant MATRIX := (1 .. 5 => (1 .. 8 => 0.0)); -- С'FIRSТ(1)=1, С'LАSТ(2)=8D : BIT_VECTOR(M .. N) := (M .. N => TRUE); -- см. 3.6E : BIT_VECTOR(M .. N) := (others => TRUE);F : STRING(1 .. 1) := (1 => 'F'); --однокомпонентный агрегат:то же, что и <F>
Ссылки: агрегат 4.3, в некотором порядке 1.6, возбуждение исключений 11, выбор 3.7.3, выражение 4.4, вычислить 4.5, диапазон индекса 3.6, именованное сопоставление компонент 4.3, индексируемый тип 3.6, исключение CONSTRAINT_ERROR 11.1, квалифицированное выражение 4.7, компонента 3.3, объект 3.2, ограничение 3.3, ограничение индекса 3.6.1, ограниченный индексируемый подтип 3.6, подкомпонента 3.3, подтип индекса 3.6, позиционное сопоставление компонент 4.3, пустой массив 3.6.1, размерность 3.6, сопоставление компонент 4.3, составной ограничитель присваивания 5.2, статическое выражение 4.9, тип 3.3, тип индекса 3.6, тип компоненты 3.3, фактический параметр 6.4.1, формальный параметр 6.1, функция 6.5.