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

3.7 Дискриминанты

Составной тип (кроме массива или типа интерфейса) может иметь дискриминанты, которые параметризуют тип. known_discriminant_part задает дискриминанты составного типа. Дискриминант объекта является компонентом объекта и имеет дискретный или указательный тип. unknown_discriminant_part в объявлении вида типа указывает, что дискриминанты типа неизвестны для данного вида; все подтипы такого вида являются неопределенными подтипами.

Синтаксис

discriminant_part ::= unknown_discriminant_part | known_discriminant_part
unknown_discriminant_part ::= (<>)
known_discriminant_part ::=
(discriminant_specification {; discriminant_specification})
discriminant_specification ::=
defining_identifier_list : [null_exclusion] subtype_mark [:= default_expression]
| defining_identifier_list : access_definition [:= default_expression]
default_expression ::= expression

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

Ожидаемый тип для default_expression спецификации дискриминанта соответствует типу соответствующего дискриминанта.

Правила допустимости

discriminant_part разрешается только в объявлении составного типа, который не является массивом или типом интерфейса (это включает формальные типы обобщенных типов). Тип, объявленный с known_discriminant_part, называется дискриминируемым типом, как и тип, который наследует (известные) дискриминанты.
Подтип дискриминанта может быть определен необязательным null_exclusion и subtype_mark, в этом случае subtype_mark должен обозначать дискретный или указательный подтип, или может быть определен с помощью access_definition. Дискриминант, определенный с помощью access_definition, называется указательным дискриминантом и имеет анонимный тип указателя.
Default_expression должны быть предоставлены либо для всех, либо ни для одного дискриминанта known_discriminant_part. default_expression не разрешены в known_discriminant_part в объявлении помеченного типа или формального типа обобщенного типа.
discriminant_specification для указательного дискриминанта может иметь default_expression только в объявлении для задачи или защищенного типа, или для типа, являющегося потомком явным образом ограниченного типа записи. В дополнение к местам, где обычно применяются Правила допустимости (см. 12.3), это правило применяется также в частях с частным объявлением экземпляра обобщенного блока.
Этот абзац был удален.
Для типа, определенного derived_type_definition, если в его объявлении предоставлен known_discriminant_part, то:
  • Родительский подтип должен быть ограничен;
  • Если родительский тип не является помеченным типом, то каждый дискриминант производного типа должен использоваться в ограничении, определяющем родительский подтип;
  • Если дискриминант используется в ограничении, определяющем родительский подтип, подтип дискриминанта должен быть статически совместим (см. 4.9.1) с подтипом соответствующего родительского дискриминанта.
Тип default_expression, если таковой имеется, для указательного дискриминанта должен быть преобразуем к анонимному указательному типу дискриминанта (см. 4.6).

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

discriminant_specification объявляет дискриминант; subtype_mark обозначает его подтип, если он не является указательным дискриминантом, в этом случае подтип дискриминанта — это анонимный подтип указателя на переменную, определенный access_definition.
Для типа, определенного с помощью derived_type_definition, каждый дискриминант родительского типа наследуется, ограничивается значением нового дискриминанта производного типа или ограничивается значением выражения. При наследовании или ограничении равным некоторым новым дискриминантом производного типа родительский дискриминант и дискриминант производного типа считаются соответствующими. Два дискриминанта также соответствуют, если существует общий дискриминант, которому они оба соответствуют. Дискриминант соответствует самому себе. Если дискриминант родительского типа ограничен определенным значением с помощью derived_type_definition, то этот дискриминант считается указанным этим derived_type_definition.
constraint, который появляется в определении дискриминированного типа, зависит от дискриминанта типа, если он называет дискриминант как границу или значение дискриминанта. component_definition зависит от дискриминанта, если его constraint зависит от дискриминанта или от дискриминанта, который ему соответствует.
Компонент зависит от дискриминанта, если:
  • Его component_definition зависит от дискриминанта; или
  • Он объявлен в variant_part, который управляется дискриминантом; или
  • Это компонент, унаследованный в рамках derived_type_definition, и constraint parent_subtype_indication зависит от дискриминанта; или
  • Это подкомпонент компонента, который зависит от дискриминанта.
Каждое значение дискриминированного типа включает значение для каждого компонента типа, который не зависит от дискриминанта; это включает сами дискриминанты. Значения дискриминантов определяют, какие другие значения компонентов присутствуют в значении дискриминированного типа.
Тип, объявленный с known_discriminant_part, имеет известные дискриминанты; его первый подтип не ограничен. Тип, объявленный с unknown_discriminant_part, имеет неизвестные дискриминанты. Тип, объявленный без discriminant_part, не имеет дискриминантов, если это не производный тип; если производный, такой тип имеет тот же вид дискриминантов (известные, неизвестные или отсутствующие) что и родительский (или предковый) тип. Тип меченого класса также имеет неизвестные дискриминанты. Любой подтип типа с неизвестными дискриминантами является неограниченным и неопределенным подтипом (см. 3.2 и 3.3).

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

Для указательного дискриминанта его access_definition обрабатывается, когда значение указательного дискриминанта определяется: путем оценки его default_expression, обработкой discriminant_constraint, или путем присваивания, инициализирующего окружающий объект.
ПРИМЕЧАНИЯ
52 Если у дискриминируемого типа есть default_expression для его дискриминантов, то разрешены несо ограниченные переменные типа, и значения дискриминантов могут быть изменены присваиванием такой переменной. Если значения по умолчанию не заданы для дискриминантов, то все переменные типа ограничены, либо явным ограничением, либо своим начальным значением; значения дискриминантов такой переменной не могут быть изменены после инициализации.
53 default_expression для дискриминанта типа вычисляется при создании объекта не ограниченного подтипа типа.
54 Присваивание дискриминанту объекта (после его инициализации) запрещено, так как имя дискриминанта является константой; ни assignment_statement, ни присваивания, присущие передаче в качестве параметра in out или out, не разрешены. Однако обратите внимание, что значение дискриминанта может быть изменено путём присваивания заключённому объекту, предполагая, что это не ограниченная переменная.
55 Дискриминант, который является именованным типом доступа, не называется дискриминантом доступа; это понятие используется только для дискриминантов, определённых access_definition.

Примеры

Примеры дискриминируемых типов:
type Buffer(Size : Buffer_Size := 100) is -- см. 3.5.4
record
Pos : Buffer_Size := 0;
Value : String(1 .. Size);
end record;
type Matrix_Rec(Rows, Columns : Integer) is
record
Mat : Matrix(1 .. Rows, 1 .. Columns); -- см. 3.6
end record;
type Square(Side : Integer) is new
Matrix_Rec(Rows => Side, Columns => Side);
type Double_Square(Number : Integer) is
record
Left : Square(Number);
Right : Square(Number);
end record;
task type Worker(Prio : System.Priority; Buf : access Buffer) is
-- дискриминанты, используемые для параметризации типа задачи (см. 9.1)
pragma Priority(Prio); -- см. D.1
entry Fill;
entry Drain;
end Worker;


Spec-Zone.ru

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