Конкретизация настройки
Экземпляр настраиваемого модуля описывается конкретизацией настройки.
конкретизация - настройки ::= package идентификатор is new имя-настраиваемого-пакета [раздел - фактических - параметров - настройки]; | procedure идентификатор is new имя- настраиваемой -процедуры [раздел - фактических - параметров - настройки]; | function обозначение is new имя-настраиваемой-функции [раздел - фактических - параметров - настройки];
раздел-фактических-параметров-настройки ::= (сопоставление-параметров-настройки {, сопоставление-параметров-настройки}
сопоставление-параметров-настройки ::= [формальный-параметр-настройки = >] фактический-параметр-настройки
формальный-параметр-настройки ::= простое-имя-параметра | знак-операции
фактический-параметр-настройки :: = выражение имя-переменной | имя-подпрограммы имя-входа
| обозначение-типа
Для каждого формального параметра настройки должен быть задан явный фактический параметр настройки, кроме случая, когда соответствующим описанием параметра настройки задана форма умолчания. Сопоставление параметров настройки может быть либо позиционным, либо именованным (как в вызове подпрограммы (см. 6.4)). Если две или несколько формальных подпрограмм имеют одно и то же обозначение, то для соответствующих параметров настройки именованные сопоставления недопустимы.
Каждый фактический параметр настройки должен быть
сопоставлен с
соответствующим формальным параметром. Выражение может быть сопоставлено с формальным объектом вида
in;
имя переменной может быть сопоставлено с формальным объектом вида
in out;
имя подпрограммы или имя входа может сопоставляться с формальной подпрограммой; обозначение типа может сопоставляться с формальным типом. Детальные правила, определяющие единственные допустимые сопоставления, даны в разд. 12.3.1 — 12.3.6.
Экземпляр — это копия настраиваемого модуля без его раздела формальных параметров настройки; таким образом, экземпляр настраиваемого пакета — пакет, настраиваемой процедуры — процедура, настраиваемой функции — функция.
Для каждого вхождения обозначающего данное понятие имени в настраиваемый модуль следующий список определяет, какое понятие соответствует этому имени в экземпляре.
а) Имя обозначает настраиваемый модуль: соответствующее вхождение обозначает экземпляр.
б) Имя обозначает формальный объект настройки вида
in:
соответствующее в экземпляре имя обозначает константу, значение которой — копия значения сопоставленного фактического параметра настройки.
в) Имя обозначает формальный объект настройки вида
in out:
соответствующее в экземпляре имя обозначает переменную, указанную сопоставленным фактическим параметром настройки.
г) Имя обозначает формальный тип настройки: соответствующее в экземпляре имя обозначает подтип, указанный сопоставленным фактическим параметром настройки (фактическим подтипом).
д) Имя обозначает дискриминант формального типа настройки: соответствующее в экземпляре имя обозначает соответствующий дискриминант (он должен быть один) фактического типа, сопоставленного формальному типу настройки.
е) Имя обозначает формальную подпрограмму настройки: соответствующее в экземпляре имя обозначает подпрограмму, литерал перечисления или вход, указанный сопоставленным фактическим параметром настройки (фактической подпрограммой).
ж) Имя обозначает формальный параметр формальной подпрограммы настройки: соответствующее в экземпляре имя обозначает соответствующий формальный параметр фактической подпрограммы, соответствующей формальной подпрограмме.
з) Имя обозначает локальное понятие, описанное в настраиваемом модуле: соответствующее в экземпляре имя обозначает понятие, описанное соответствующим локальным описанием в экземпляре.
и) Имя обозначает глобальное понятие, описанное вне настраиваемого модуля: соответствующее в экземпляре имя обозначает это же глобальное понятие.
Те же правила справедливы для знаков операций и базовых операций; в частности, для формальных операций верно правило е), для локальных операций — правило з) и для операций над глобальными типами — правило и).
Кроме того, если в настраиваемом модуле используется предопределенная операция или базовая операция над формальным типом, то в экземпляре используется предопределенная операция, соответствующая фактическому типу, сопоставленному формальному.
Эти же правила применяются к обозначению типа и выражению (по умолчанию) из раздела формальных параметров настройки настраиваемого модуля.
При предвыполнении конкретизации настройки осуществляются следующие действия. Сначала вычисляется каждое выражение, заданное в качестве явного фактического параметра настройки, и каждое выражение, входящее как составная часть в имя переменной или входа, заданное в качестве явного фактического параметра настройки; в языке не определен порядок вычисления этих выражений. Затем вычисляются выражения или имена по умолчанию для тех параметров, для которых опущены сопоставления параметров (если они есть) настройки; эти вычисления производятся в порядке следования описаний формальных параметров настройки. Наконец, предвыполняется неявно сгенерированный экземпляр. Предвыпо-лнение конкретизации настройки может также вызывать проверки некоторых ограничений, как описано ниже.
Рекурсивная конкретизация настройки недопустима в следующем смысле: если данный настраиваемый модуль включает конкретизацию другого настраиваемого модуля, то экземпляр, сгенерированный этой конкретизацией, не должен включать экземпляр первого настраиваемого модуля (независимо от того, генерируется ли этот экземпляр непосредственно или косвенно через промежуточную конкретизацию).
Примеры конкретизации настройки
(см.
12.1}:
procedure SWAP is new EXCHANGE(ELEM => INTEGER); procedure SWAP is new EXCHANGE(CHARACTER); -- совмещение идентификатора SWAP function SQUARE is new SQUARING (INTEGER); -- по умолчанию используется «*» над INTEGER function SQUARE is new SQUARING (ITEM => MATRIX, "*" => MATRIX_PRODUCT); function SQUARE is new SQUARING (MATRIX, MATRIX_PRODUCT); -- что эквивалентно предыдущему package INT_VECTORS is new ON_VECTORS(INTEGER, TABLE, "+");
Примеры использования конкретизированных модулей:
SWAP(A, 8); А := SQUARE(A); Т : TABLE(1 .. 5) := (10, 20, 30, 40, 50); N : INTEGER := INT_VECTORS.SIGMA(T); -- 150 (CM. 12.2)
use INT_VECTORS; М : INTEGER := SIGMA(T); -— 150
Примечание.
Опускать параметр настройки допускается только тогда, когда для него существует умолчание. Если использованы выражение по умолчанию или (отличные от простых) имена по умолчанию, то они вычисляются в том порядке, в котором описаны соответствующие формальные параметры настройки.
Если две совмещенные подпрограммы описаны в спецификации настраиваемого пакета и различаются только (формальным) типом параметров и результата, то существуют'правильные конкретизации, для которых все вызовы этих подпрограмм вне экземпляра будут неоднозначными. Например:
generic
type A is (<>); type В is private;
package G is
function NEXT(X : A) return A; function NEXT(X : B) return B; end;
package P is new G(A => BOOLEAN. B => BOOLEAN); -— все вызовы P.NEXT неоднозначны
Ссылки:
вид
in
12.1.1, вид
in out
12.1.1, видимость 8.3, вызов подпрограммы 6.4, выражение 4.4, вычисление 4.5, глобальное описание 8.1, дискриминант 3.7.1, знак операции 6.1, идентификатор 2.3, имя 4.1, имя входа 9.5, имя подпрограммы 6.1, локальное описание 8.1, неявное описание 3.1, обозначение 6.1, обозначение типа 3.3.2, описание 3.1, описание подтипа 3.3.2, операция типа 3.3, описание формального параметра настройки 12.1, пакет 7, переменная 3.2.1, подпрограмма 6, понятие 3.1, предвыполнение 3.1, 3.9, простое имя 4.1, совмещение 6.6, 8.7, формальная подпрограмма настройки 12.1, формальный объект настройки 12.1, формальный параметр настройки 12.1, формальный тип настройки 12.1.
12.3.1. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ОБЪЕКТОВ
Формальному параметру настройки вида
tn
данного типа сопоставляется выражение этого же типа. Если настраиваемый модуль имеет формальный объект настройки вида
in,
то проверяется принадлежность значения выражения подтипу, заданному обозначением типа, как и для явного описания константы (см. 3.2.1).
При отрицательном результате проверки возбуждается исключение CONSTRAINT-ERROR.
Формальному параметру настройки вида
in out
данного типа сопоставляется имя переменной этого же типа. Переменная не должна быть формальным параметром вида
out
или его подкомпонентой. Имя должно обозначать такую переменную, для которой допустимо переименование (см. 8.5).
Примечание.
Тип фактического параметра настройки вида
in
не должен быть лимитируемым типом. Ограничения формального параметра настройки вида
in out
являются ограничениями соответствующего фактического параметра настройки (см. 12.2.1).
Ссылки:
вид
in
12.1.1, вид
in out
12.1.1, вид
out
6.2, возбуждение исключения 11, выражение 4.4, имя 4.1, исключение CONSTRAINT-ERROR 11.1, конкретизация настройки 12.3, лимитируемый тип 7.4.4, настраиваемый модуль 12.1, обозначение типа 3.3.2, ограничение 3.3, переменная 3.2.1, подкомпонента 3.3, сопоставление фактических параметров настройки 12.3, тип 3.3, удовлетворять 3.3, фактический параметр настройки 12.3, формальный объект настройки 12.1.1, формальный параметр 6.1, формальный параметр настройки 12.1.
12.3.2. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ЛИЧНЫХ ТИПОВ
Формальный личный тип настройки сопоставляется с типом или подтипом (фактическим подтипом), удовлетворяющим следующим условиям:
•Если формальный тип не является лимитируемым, то фактический тип не должен быть лимитируемым. (С другой стороны, если формальный тип является лимитируемым, то соответствующий фактический тип может быть лимитируемым и нелимитируемым.)
•Если формальный тип имеет раздел дискриминантов, то фактический тип должен быть типом с таким же числом дискриминантов; тип дискриминанта в данной позиции в разделе дискриминантов фактического типа должен совпадать с типом дискриминанта в той же позиции раздела дискриминантов формального типа; фактический подтип должен быть неограниченным. (С другой стороны, если формальный тип не имеет дискриминантов, для фактического типа дискриминанты допустимы.)
Ниже рассматривается вхождение имени формального типа в том месте, где оно использовано как указание неограниченного подтипа. Фактический подтип не должен быть неограниченным индексируемым типом или неограниченным типом с дискриминантами, если любое вхождение находится на месте, где для индексируемого типа или типа с дискриминантами требуется либо ограничение, либо выражения по умолчанию для дискриминантов (см. 3.6.1 и 3.7.2). Такое же требование предъявляется ко всем вхождениям имени подтипа формального типа, а также к вхождениям имени любого типа или подтипа, производного (непосредственно или косвенно) для этого формального типа.
Если настраиваемый модуль имеет формальный личный тип с дискриминантами, то при предвыполнении соответствующей конкретизации настройки проверяется совпадение подтипа каждого дискриминанта фактического типа и подтипа соответствующего дискриминанта формального типа. При несовпадении таких подтипов возбуждается исключение CONSTRAINT-ERROR.
Ссылки:
возбуждение исключения 11, выражение по умолчанию для дискриминанта 3.7.1, дискриминант 3.7.1, имя 4.1, индексируемый тип 3.1, исключение CONSTRAINT-ERROR 11.1, конкретизация настройки 12.3, лимитируемый тип 7.4.4, личный тип 7.4, настраиваемое тело 12.2, неограниченный индексируемый тип 3.6, неограниченный подтип 3.3, обозначение подтипа 3.3.2, ограничение 3.3, подтип 3.3, предвыполнение 3.9, производный тип 3.4, раздел дискриминантов 3.7.1, сопоставление фактических параметров настройки 12.3, спецификация настройки 12.1, тип 3.3, тип с дискриминантами 3.3, фактический тип настройки 12.3, формальный тип настройки 12.1.2.
12.3.3. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ СКАЛЯРНЫХ ТИПОВ
Формальному типу настройки, определенному символами (о), сопоставляется любой дискретный подтип (т.е. любой перечислимый или целый подтип). Формальному типу настройки, определенному символами
range о,
сопоставляется любой целый подтип. Формальному типу настройки, определенному символами
digits о,
сопоставляется любой плавающий подтип.
Формальному типу настройки, определенному символами
delta о,
сопоставляется любой фиксированный подтип. Никакие другие сопоставления для этих формальных типов настройки невозможны.
Ссылки:
бокс 12.1.2, дискретный тип 3.5, определение настраиваемого типа 12.1, перечислимый тип 3.5.1, плавающий тип 3.5.7, скалярный тип 3.5, сопоставление фактических параметров настройки 12.3, фактический тип настройки 12.1.2, фиксированный тип 3.5.9, формальный тип настройки 12.1.2, целый тип 3.5.4.
12.3.4. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ИНДЕКСИРУЕМЫХ ТИПОВ
Формальному индексируемому типу сопоставляется фактический индексируемый подтип, удовлетворяющий следующим условиям:
•Формальный и фактический индексируемые типы должны иметь одинаковые размерности; формальный тип и фактический подтип должны быть либо оба ограниченными, либо оба неограниченными.
•Для каждой позиции индекса тип индекса фактического индексируемого типа должен совпадать с типом индекса формального индексируемого типа.
•Типы компонент фактического и формального индексируемых типов должны быть одинаковыми. Если тип компоненты отличен от скалярного, то подтипы компонент фактического и формального индексируемых типов должны быть либо оба ограниченными, либо оба неограниченными.
Если настраиваемый модуль имеет формальный индексируемый тип, то при предвыполнении соответствующей конкретизации проверяются совпадения ограничений (если они есть) на тип компоненты фактического индексируемого типа с ограничениями для формального индексируемого типа; для любой данной позиции индекса индексируемых подтипов или дискретных диапазонов проверяется совпадение границ. При несовпадениях возбуждается исключение CONSTRAINT-ERROR.
Пример:
-- задание настраиваемого пакета generic
type ITEM is private;
type INDEX is (<>»; type VECTOR is array (INDEX range <>) of ITEM; type TABLE is array (INDEX) of ITEM;
package P is
... end;
—- даны типы type MIX is array (COLOR range <>) of BOOLEAN; type OPTION is array (COLOR) of BOOLEAN;
—- теперь тип MIX может быть сопоставлен типу VECTOR, a —- OPTION — типу TABLE
package R is new P(ITEM => BOOLEAN, INDEX => COLOR, VECTOR => MIX, TABLE => OPTION);
—- теперь тип MIX не может быть сопоставлен типу TABLE, —- а тип OPTION — типу VECTOR
Примечание.
Если тип любого индекса или тип компоненты формального индексируемого типа сам является формальным типом, то по приведенным правилам в экземпляре его имя обозначает соответствующий фактический подтип (см. 12.3 г)).
Ссылки:
индекс 3.6, индексируемый тип 3.6, исключение CONSTRAINT-ERROR 11.1, компонента массива 3.6, конкретизация настройки 12.3, неограниченный индексируемый тип 3.6, ограничение 3.3, ограничение индекса 3.6.1, ограниченный индексируемый тип 3.6, оператор возбуждения исключения 11.3, определение индексируемого типа 3.6, подтип 3.3, предвыполнение 3.9, сопоставление фактических параметров настройки 12.3, формальный тип 12.1, формальный тип настройки 12.1.2.
12.3.5. ПРАВИЛО СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ССЫЛОЧНЫХ ТИПОВ
Формальному ссылочному типу сопоставляется фактический ссылочный подтип, если тип указываемых объектов для формального и фактического типов один и тот же. Если указываемый тип отличен от скалярного, то указываемые подтипы должны быть либо оба ограниченными, либо оба неограниченными.
Если настраиваемый модуль имеет формальный ссылочный тип, то при предвыполнении соответствующей конкретизации проверяется совпадение любых ограничений на указанные объекты фактического и формального ссылочных типов. При несовпадении возбуждается исключение CONSTRAINT-ERROR.
Пример:
-- формальным типам настраиваемого пакета
generic
type NODE is private;
type LINK is accees NODE; package P is
... end:
-- могут быnь сопоставлены фактические типы
type CAR; type CAR_NAME is access CAR; type CAR is record
PRED, SUCC : CAR_NAME; NUMBER : LICENSE_NUMBER; OWNER : PERSON; end record;
-- в следующей конкретизации настройки package R is new P(NODE => CAR, LINK => CAR_NAME);
Примечание.
Если указанный тип сам является формальным, то в соответствии с описанными выше правилами в экземпляре его имя обозначает соответствующий фактический подтип (см. 12.3 г)).
Ссылки:
значение ссылочного типа 3.8, исключение CONSTRAINT-ERROR 11.1, конкретизация настройки 12.3, объект 3.2, ограничение 3.3, оператор возбуждения исключения 11.3, определение ссылочного типа 3.8, предвыполнение 3.9, сопоставление фактических параметров настройки 12.3, ссылочный тип 3.8, указывать 3.8, формальный тип настройки 12.1.2.
12.3.6. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ПОДПРОГРАММ
Формальной подпрограмме сопоставляется фактическая подпрограмма, литерал перечисления или вход, если в первом и последнем случаях профиль типов параметров и результата один и тот же (см. 6.6) и виды формальных и фактических параметров в одинаковых позициях должны быть одинаковыми.
Если настраиваемый модуль имеет формальную подпрограмму, заданную именем, то это имя должно обозначать подпрограмму, литерал перечисления или вход, сопоставленные формальной подпрограмме (в указанном выше смысле). Вычисление имени по умолчанию производится во время предвыполнения каждой конкретизации, в которой используется это умолчание, как определено в разд. 12.3.
Если настраиваемый модуль имеет подпрограмму по умолчанию, специфицированную как бокс, то соответствующий фактический параметр может быть опущен, если подпрограмма, литерал перечисления или вход, сопоставляемые формальной подпрограмме, имеют то же обозначение, что и формальная подпрограмма, и непосредственно на месте конкретизации должна быть видима единственная такая подпрограмма, или литерал перечисления, или вход.
Пример:
-- дана спецификация настраиваемой функции generic
type ITEM is private;
with function "*" (U, V : ITEM) return ITEM is <>;
function SQUARING(X : ITEM) return ITEM;
-- и функция function MATRIX_PRODUCT(A, В : MATRIX) return MATRIX;
-- возможна следующая конкретизация
function SQUARE is new SQUARING(MATRIX, MATRIX„PRODUCT):
-- следующие конкретизации эквивалентны function SQUARE is new SQUARING(ITEM => INTEGER, "*" => "*");
function SQUARE is new SQUARING(INTEGER, "*");
function SQUARE is new SQUARING(INTEGER);
Примечание.
Правила сопоставления для формальных подпрограмм устанавливают требования, которые подобны требованиям, применяемым к описаниям переименования подпрограмм (см. 8.5). В частности, не требуется совпадения имен соответствующих параметров формальной и фактической подпрограмм; аналогично для таких параметров не обязательно соответствие выражений по умолчанию.
Формальной подпрограмме сопоставляется атрибут типа, если этот атрибут — функция с сопоставимой спецификацией. Литерал перечисления данного'типа сопоставляется с формальной функцией без параметров и результатом данного типа.
Ссылки:
атрибут 4.1.4, видимость 8.3, вход 9.5, имя 4.1, конкретизация настройки 12.3, обозначение 6.1, ограничитель бокс 12.1.2, подпрограмма 6, подтип 3.3, профиль типа параметров и результата 6.3, сопоставление фактических параметров настройки 12.3, спецификация подпрограммы 6.1, фактический тип настройки 12.3, формальная подпрограмма настройки 12.1, формальный тип настройки 12.1.2, функция 6.5.
Пред. | Уровень выше | След. |
12.2. НАСТРАИВАЕМЫЕ ТЕЛА |
Содержание | 12.4. ПРИМЕР НАСТРАИВАЕМОГО ПАКЕТА |