Spec-Zone.ru › Ada 2012
Справочное руководство Ada 2012

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_specification соответствует типу соответствующего дискриминанта.

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

Часть 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 только в объявлении неизменяемого лимитированного типа (см. 7.5). Помимо мест, где обычно применяются правила легальности (см. 12.3), это правило применяется также в частях приватного объявления экземпляра обобщённого блока.
Этот абзац был удалён.
Для типа, определённого derived_type_definition, если в его объявлении предоставлена known_discriminant_part, то:
  • Родительский подтип должен быть ограничен;
  • Если родительский тип не является помеченным типом, то каждый дискриминант производного типа должен использоваться в ограничении, определяющем родительский подтип;
  • Если дискриминант используется в ограничении, определяющем родительский подтип, то подтип дискриминанта должен быть статически совместимым (см. 4.9.1) с подтипом соответствующего родительского дискриминанта.
Этот абзац был удалён.

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

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

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

Для дискриминанта доступа его access_definition уточняется, когда значение дискриминанта доступа определяется: путём оценки default_expression, путём уточнения discriminant_constraint или путём присваивания, инициализирующего окружающий объект.
ПРИМЕЧАНИЯ
58 Если дискриминируемый тип имеет default_expression для своих дискриминантов, то допускаются нескомпонованные переменные типа, и значения дискриминантов могут быть изменены присваиванием такой переменной. Если значения по умолчанию для дискриминантов не указаны, то все переменные типа ограничены, либо явным ограничением, либо своим начальным значением; значения дискриминантов такой переменной нельзя изменить после инициализации.
59 default_expression для дискриминанта типа вычисляется при создании объекта нескомпонованного подтипа типа.
60 Присваивание дискриминанту объекта (после его инициализации) запрещено, так как имя дискриминанта является константой; ни операторы assignment_statement, ни присваивания, неявные при передаче в качестве параметра in out или out, не допускаются. Однако, значение дискриминанта может быть изменено присваиванием заключённому объекту, предполагая, что это нескомпонованная переменная.
61 Дискриминант, являющийся типом с именем, не называется дискриминантом доступа; это понятие используется только для дискриминантов, определённых с помощью 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)
with Priority => Prio is -- см. D.1
-- дискриминанты, используемые для параметризации типа задачи (см. 9.1)
entry Fill;
entry Drain;
end Worker;


Spec-Zone.ru

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