Справочник Ada 2012
4.3.2 Расширяющие агрегаты
Расширяющий агрегат extension_aggregate задает значение для типа-расширения записи, указывая значение или подтип предка типа, за которым следуют ассоциации для любых компонентов, не определённых частью ancestor_part.
Синтаксис
Правила разрешения имён
Ожидаемый тип для расширяющего агрегата extension_aggregate должен быть единственным типом, являющимся расширением записи. Если ancestor_part представляет выражение, ожидается, что оно будет любого типа с меткой.
Правила допустимости
Если ancestor_part представляет метка_подтипа, она должна обозначать конкретный меченный подтип. Если ancestor_part представляет выражение, оно не должно быть динамически меченным. Тип extension_aggregate должен быть потомком типа ancestor_part (тип предок) через одно или несколько расширений записей (и без расширений с приватностью). Если ancestor_part представляет метка_подтипа, представление предка типа, от которого происходит наследование (см. 7.3.1), не должно иметь неизвестных дискриминантов.
Если тип ancestor_part ограничен, и хотя бы один компонент необходим в record_component_association_list, то ancestor_part не должен быть:
- вызовом функции с неограниченным подтипом результата; ни
- скобками или квалифицированным выражением, операнд которого нарушил бы это правило; ни
- условным выражением conditional_expression с хотя бы одним зависимым выражением, которое нарушило бы это правило.
Статическая семантика
Для record_component_association_list расширяющего агрегата extension_aggregate, необходимыми являются только те компоненты составного значения, определяемого агрегатом, которые не унаследованы от типа ancestor_part, плюс любые унаследованные дискриминанты, если ancestor_part является метка_подтипа, которая обозначает неограниченный подтип.
Динамическая семантика
Для оценки расширяющего агрегата extension_aggregate, вычисляется record_component_association_list. Если ancestor_part является выражением, оно также вычисляется; если ancestor_part является метка_подтипа, компоненты значения агрегата, не заданные record_component_association_list, инициализируются по умолчанию, как для объекта предка типа. Любые неявные инициализации или вычисления выполняются в произвольном порядке, за исключением того, что выражение для дискриминанта вычисляется до любого другого вычисления или инициализации, зависящего от него.
Если тип ancestor_part имеет дискриминанты, и ancestor_part не является метка_подтипа, обозначающей неограниченный подтип, то проверяется, что каждый дискриминант, определенный ancestor_part, имеет значение, указанное для соответствующего дискриминанта, если таковой имеется, либо в record_component_association_list, либо в derived_type_definition для какого-либо предка типа extension_aggregate. Если проверка не пройдена, генерируется Constraint_Error.
ПРИМЕЧАНИЯ
9 Если все компоненты значения extension_aggregate определяются ancestor_part, то record_component_association_list должен быть просто null record.
10 Если ancestor_part представляет метка_подтипа, то его тип может быть абстрактным. Если его тип контролируется, то в качестве последнего шага оценки агрегата вызывается процедура Initialize предка типа, если процедура Initialize не абстрактна (см. 7.6).
Примеры
Примеры расширяющих агрегатов (для типов, определённых в 3.9.1):
Painted_Point'(Point with Red)
(Point'(P) with Paint => Black)
(Point'(P) with Paint => Black)
(Expression with Left => 1.2, Right => 3.4)
Addition'(Binop with null record)
-- предполагая, что Binop типа Binary_Operation
Addition'(Binop with null record)
-- предполагая, что Binop типа Binary_Operation