Справочное руководство по языку Ада-83



Справочное руководство по языку Ада-83

         

Настраиваемые модули


Настраиваемый модуль — это программный модуль, являющийся настраиваемой подпрограммой или настраиваемым пакетом, это также шаблон с параметрами или без них, по которому могут быть получены соответствующие (ненастраиваемые) подпрограммы или пакеты. Итоговые программные модули называются экземплярами исходного настраиваемого модуля.

Настраиваемый модуль задается описанием настройки, которое имеет раздел формальных параметров настройки, описывающий эти параметры. Конкретный экземпляр настраиваемого модуля получается в результате конкретизации настройки путем сопоставления формальным параметрам фактических. Экземпляр настраиваемой подпрограммы — это подпрограмма. Экземпляр настраиваемого пакета — пакет.

Как шаблоны настраиваемые модули не обладают свойствами, характерными для их ненастраиваемых аналогов. Например, настраиваемая подпрограмма может быть конкретизирована, но не может быть вызвана. В отличие от нее экземпляр настраиваемой подпрограммы может быть вызван, но не может использоваться для изготовления других экземпляров.

Ссылки: конкретизация настройки 12.3, настраиваемый пакет 12.1, настраиваемая подпрограмма 12.1, описание 3.1, описание настройки 12.1, пакет 7, подпрограмма 6, программный модуль 6, раздел формальных параметров настройки 12.1, фактический параметр настройки 12.3, формальный параметр настройки 12.1, экземпляр



Конкретизация настройки


Экземпляр настраиваемого модуля описывается конкретизацией настройки.

конкретизация - настройки ::= package идентификатор is new имя-настраиваемого-пакета [раздел - фактических - параметров - настройки];

| procedure идентификатор is new имя- настраиваемой -процедуры [раздел - фактических - параметров - настройки]; | function обозначение is new имя-настраиваемой-функции [раздел - фактических - параметров - настройки];раздел-фактических-параметров-настройки ::= (сопоставление-параметров-настройки {, сопоставление-параметров-настройки}сопоставление-параметров-настройки ::= [формальный-параметр-настройки = >] фактический-параметр-настройкиформальный-параметр-настройки ::= простое-имя-параметра | знак-операциифактический-параметр-настройки :: = выражение имя-переменной | имя-подпрограммы имя-входа | обозначение-типа

Для каждого формального параметра настройки должен быть задан явный фактический параметр настройки, кроме случая, когда соответствующим описанием параметра настройки задана форма умолчания. Сопоставление параметров настройки может быть либо позиционным, либо именованным (как в вызове подпрограммы (см. 6.4)). Если две или несколько формальных подпрограмм имеют одно и то же обозначение, то для соответствующих параметров настройки именованные сопоставления недопустимы.

Каждый фактический параметр настройки должен быть сопоставлен с соответствующим формальным параметром. Выражение может быть сопоставлено с формальным объектом вида in; имя переменной может быть сопоставлено с формальным объектом вида in out; имя подпрограммы или имя входа может сопоставляться с формальной подпрограммой; обозначение типа может сопоставляться с формальным типом. Детальные правила, определяющие единственные допустимые сопоставления, даны в разд. 1 — 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 1, вид in out 1, видимость 8.3, вызов подпрограммы 6.4, выражение 4.4, вычисление 4.5, глобальное описание 8.1, дискриминант 1, знак операции 6.1, идентификатор 2.3, имя 4.1, имя входа 9.5, имя подпрограммы 6.1, локальное описание 8.1, неявное описание 3.1, обозначение 6.1, обозначение типа 2, описание 3.1, описание подтипа 2, операция типа 3.3, описание формального параметра настройки 12.1, пакет 7, переменная 1, подпрограмма 6, понятие 3.1, предвыполнение 3.1, 3.9, простое имя 4.1, совмещение 6.6, 8.7, формальная подпрограмма настройки 12.1, формальный объект настройки 12.1, формальный параметр настройки 12.1, формальный тип настройки

1. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ОБЪЕКТОВ

Формальному параметру настройки вида tn данного типа сопоставляется выражение этого же типа. Если настраиваемый модуль имеет формальный объект настройки вида in, то проверяется принадлежность значения выражения подтипу, заданному обозначением типа, как и для явного описания константы (см. 1). При отрицательном результате проверки возбуждается исключение CONSTRAINT-ERROR.

Формальному параметру настройки вида in out данного типа сопоставляется имя переменной этого же типа. Переменная не должна быть формальным параметром вида out или его подкомпонентой. Имя должно обозначать такую переменную, для которой допустимо переименование (см. 8.5).

Примечание. Тип фактического параметра настройки вида in не должен быть лимитируемым типом. Ограничения формального параметра настройки вида in out являются ограничениями соответствующего фактического параметра настройки (см. 1).

Ссылки: вид in 1, вид in out 1, вид out 6.2, возбуждение исключения 11, выражение 4.4, имя 4.1, исключение CONSTRAINT-ERROR 11.1, конкретизация настройки 12.3, лимитируемый тип 4, настраиваемый модуль 12.1, обозначение типа 2, ограничение 3.3, переменная 1, подкомпонента 3.3, сопоставление фактических параметров настройки 12.3, тип 3.3, удовлетворять 3.3, фактический параметр настройки 12.3, формальный объект настройки 1, формальный параметр 6.1, формальный параметр настройки

2. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ЛИЧНЫХ ТИПОВ

Формальный личный тип настройки сопоставляется с типом или подтипом (фактическим подтипом), удовлетворяющим следующим условиям:

•Если формальный тип не является лимитируемым, то фактический тип не должен быть лимитируемым. (С другой стороны, если формальный тип является лимитируемым, то соответствующий фактический тип может быть лимитируемым и нелимитируемым.)

•Если формальный тип имеет раздел дискриминантов, то фактический тип должен быть типом с таким же числом дискриминантов; тип дискриминанта в данной позиции в разделе дискриминантов фактического типа должен совпадать с типом дискриминанта в той же позиции раздела дискриминантов формального типа; фактический подтип должен быть неограниченным. (С другой стороны, если формальный тип не имеет дискриминантов, для фактического типа дискриминанты допустимы.)

Ниже рассматривается вхождение имени формального типа в том месте, где оно использовано как указание неограниченного подтипа. Фактический подтип не должен быть неограниченным индексируемым типом или неограниченным типом с дискриминантами, если любое вхождение находится на месте, где для индексируемого типа или типа с дискриминантами требуется либо ограничение, либо выражения по умолчанию для дискриминантов (см. 1 и 2). Такое же требование предъявляется ко всем вхождениям имени подтипа формального типа, а также к вхождениям имени любого типа или подтипа, производного (непосредственно или косвенно) для этого формального типа.

Если настраиваемый модуль имеет формальный личный тип с дискриминантами, то при предвыполнении соответствующей конкретизации настройки проверяется совпадение подтипа каждого дискриминанта фактического типа и подтипа соответствующего дискриминанта формального типа. При несовпадении таких подтипов возбуждается исключение CONSTRAINT-ERROR.

Ссылки: возбуждение исключения 11, выражение по умолчанию для дискриминанта 1, дискриминант 1, имя 4.1, индексируемый тип 3.1, исключение CONSTRAINT-ERROR 11.1, конкретизация настройки 12.3, лимитируемый тип 4, личный тип 7.4, настраиваемое тело 12.2, неограниченный индексируемый тип 3.6, неограниченный подтип 3.3, обозначение подтипа 2, ограничение 3.3, подтип 3.3, предвыполнение 3.9, производный тип 3.4, раздел дискриминантов 1, сопоставление фактических параметров настройки 12.3, спецификация настройки 12.1, тип 3.3, тип с дискриминантами 3.3, фактический тип настройки 12.3, формальный тип настройки 2.

3. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ СКАЛЯРНЫХ ТИПОВ

Формальному типу настройки, определенному символами (о), сопоставляется любой дискретный подтип (т.е. любой перечислимый или целый подтип). Формальному типу настройки, определенному символами range о, сопоставляется любой целый подтип. Формальному типу настройки, определенному символами digits о, сопоставляется любой плавающий подтип. Формальному типу настройки, определенному символами delta о, сопоставляется любой фиксированный подтип. Никакие другие сопоставления для этих формальных типов настройки невозможны.

Ссылки: бокс 2, дискретный тип 3.5, определение настраиваемого типа 12.1, перечислимый тип 1, плавающий тип 7, скалярный тип 3.5, сопоставление фактических параметров настройки 12.3, фактический тип настройки 2, фиксированный тип 9, формальный тип настройки 2, целый тип 4.

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 — типу TABLEpackage 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, ограничение индекса 1, ограниченный индексируемый тип 3.6, оператор возбуждения исключения 11.3, определение индексируемого типа 3.6, подтип 3.3, предвыполнение 3.9, сопоставление фактических параметров настройки 12.3, формальный тип 12.1, формальный тип настройки 2.

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, формальный тип настройки 2.

6. ПРАВИЛА СОПОСТАВЛЕНИЯ ДЛЯ ФОРМАЛЬНЫХ ПОДПРОГРАММ

Формальной подпрограмме сопоставляется фактическая подпрограмма, литерал перечисления или вход, если в первом и последнем случаях профиль типов параметров и результата один и тот же (см. 6.6) и виды формальных и фактических параметров в одинаковых позициях должны быть одинаковыми.

Если настраиваемый модуль имеет формальную подпрограмму, заданную именем, то это имя должно обозначать подпрограмму, литерал перечисления или вход, сопоставленные формальной подпрограмме (в указанном выше смысле). Вычисление имени по умолчанию производится во время предвыполнения каждой конкретизации, в которой используется это умолчание, как определено в разд.

Если настраиваемый модуль имеет подпрограмму по умолчанию, специфицированную как бокс, то соответствующий фактический параметр может быть опущен, если подпрограмма, литерал перечисления или вход, сопоставляемые формальной подпрограмме, имеют то же обозначение, что и формальная подпрограмма, и непосредственно на месте конкретизации должна быть видима единственная такая подпрограмма, или литерал перечисления, или вход.

Пример:

-- дана спецификация настраиваемой функции 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, видимость 8.3, вход 9.5, имя 4.1, конкретизация настройки 12.3, обозначение 6.1, ограничитель бокс 2, подпрограмма 6, подтип 3.3, профиль типа параметров и результата 6.3, сопоставление фактических параметров настройки 12.3, спецификация подпрограммы 6.1, фактический тип настройки 12.3, формальная подпрограмма настройки 12.1, формальный тип настройки 2, функция



Настраиваемые тела


Тело настраиваемой подпрограммы или настраиваемого пакета (настраиваемое тело) является шаблоном для тел соответствующих подпрограмм или пакетов, получаемых конкретизацией настройки. Синтаксис настраиваемого тела идентичен обычному телу.

Для каждого описания настраиваемой подпрограммы должно быть соответствующее тело.

Предвыполнение настраиваемого тела не имеет другого эффекта, кроме установления того, что тело начиная с этого момента может быть использовано в качестве шаблона для получения соответствующих экземпляров.

Пример настраиваемого тела процедуры:

procedure EXCHANGE(U, V : in out ELEM) is -—см. пример в 12.1 Т : ELEM; -- формальный тип настройки begin Т := U; U := V; V := Т; end EXCHANGE;

Пример тела настраиваемой функции:

function SQUARING(X : ITEM) return ITEM is -— см. пример в 12.1 begin return X*X; -— формальная операция «*» end;

Пример тела настраиваемого пакета:

package body ON_VECTORSis -- см. пример в 12.1 function SUM(A, В : VECTOR) return VECTOR is RESULT : VECTOR(A'RANGE); -— формальный тип VECTOR BIAS : constant INTEGER := B'FIRST - A'FIRST; begin if A'LENGTH /= B'LENGTH then raise LENGTH_ERROR; end if; for N in A'RANGE loop RESULT(N) := SUM(A(N), B(N + BIAS)); -— формальная функция SUM end loop; return RESULT; end; function SIGMA(A : VECTOR) return ITEM is TOTAL : ITEM := A(A'FIRST); -— формальный тип ITEM begin for N in A'FIRST + 1 .. A'LAST loop TOTAL := SUM(TOTAL, A(N)); -— формальная функция SUM end loop; return TOTAL; end;end;

Ссылки: конкретизация настройки 12.3, настраиваемая подпрограмма 12.1,настраиваемое тело 12.1, настраиваемый пакет 12.1, пакет 7, подпрограмма 6, Предвыполнение 3.9, тело 3.9, тело пакета 7.1, тело подпрограммы 6.3, экземпляр



Описание настройки


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

описание-настройки ::= спецификация-настройки; спецификация-настройки ::= раздел-формальных-параметров-настройки спецификация-подпрограммы | раздел-формальных-параметров-настройки спецификация-пакетараздел-формальных-параметров-настройки :: = generic {описание-параметра-настройки}описание параметра-настройки ::= список-идентификаторов :[in [out]] обозначение-типа [:= выражение]; | type идентификатор is определение-настраиваемого-типа; | описание-личного-типа | with спецификация-подпрограммы [is имя]; [ with спецификация-подпрограммы [is <>];определение*-настраиваемого-типа ::= (<>) | range <> | digits <> | delta <> | определение-индексируемого-типа | определение-ссылочного-типа

Для ссылки на соответствующие формальные параметры настройки используются такие термины: формальный объект настройки (или, короче, формальный объект}, формальный тип настройки (или, короче, формальный тип) и формальная подпрограмма настройки (или, короче, формальная подпрограмма}.

В разделе формальных параметров настройки указание подтипа допустимо только в виде обозначения типа (т.е. такое указание подтипа не должно содержать явного ограничения). Обозначение настраиваемой подпрограммы должно быть задано идентификатором.

Имя программного модуля, являющегося настраиваемым модулем, вне его спецификации и тела обозначает этот настраиваемый модуль. В отличие от этого в зоне описания, связанной с настраиваемой подпрограммой, имя такого программного модуля обозначает подпрограмму, полученную при текущей конкретизации настраиваемого модуля. Аналогично в зоне описания, связанной с настраиваемым пакетом, имя программного модуля обозначает пакет, полученный при текущей конкретизации.

Предвыполнение описания настройки не имеет другого эффекта.

Примеры разделов формальных параметров:

generic -- без параметровgeneric SIZE : NATURAL; -— формальный объектgeneric LENGTH : INTEGER := 200; -— формальный объект с выражением по умолчанию AREA : INTEGER := LENGTH*LENGTH; -— формальный объект с выражением по умолчаниюgeneric type ITEM is private; -- формальный тип type INDEX is (<>); -— формальный тип type ROW is array (INDEX range <>) of ITEM; -— формальный тип with function "<"(X, Y : ITEM) return BOOLEAN; -— формальная подпрограмма

Примеры описаний настройки с настраиваемыми подпрограммами:

generic type ELEM is private; procedure EXCHANGE (U, V : in out ELEM);generic type ITEM is private; with function "*"(U, V : ITEM) return ITEM is <>; function SQUARING(X : ITEM) return ITEM;

Пример описания настройки с настраиваемым пакетом:

generic type ITEM is private; type VECTOR is array (POSITIVE range <>) of ITEM; with function SUM(X, Y : ITEM) return ITEM; package ON_VECTORS is function SUM (А. В : VECTOR) return VECTOR; function SIGMA (A : VECTOR) return ITEM; LENGTH_ERROR : exception; end;

Примечание. Внутри тела настраиваемой подпрограммы ее имя рассматривается как имя подпрограммы. Следовательно, это имя может быть совмещено, а также может появиться в рекурсивном вызове текущей конкретизации. По этой же причине его нельзя использовать после зарезервированного слова new в (рекурсивной) конкретизации настройки.

Выражение, которое находится в разделе формальных параметров настройки, — это выражение по умолчанию для формального параметра вида in, либо составная часть имени входа, заданного как имя по умолчанию для формальной подпрограммы, либо выражение по умолчанию для параметра формальной подпрограммы. В первых двух случаях значение этого выражения вычисляется только в тех конкретизациях, в которых используется соответствующее умолчание. В третьем случае значение выражения вычисляется только в вызовах формальных подпрограмм, использующих такое умолчание. (К любому имени, используемому в выражении по умолчанию, применяются обычные правила видимости: обозначенные этим именем понятия должны быть видимы в том месте, где стоит выражение.)

Ни формальные параметры настройки, ни их атрибуты в качестве частей статических выражений недопустимы (см. 4.9).

Ссылки: атрибут 4, выражение 4.4, зарезервированное слово 2.9, идентификатор 2.3, имя 4.1, конкретизация настройки 12.3, обозначение 6.1, обозначение типа 2, объект 3.2, ограничение 3.3, описание 3.1, определение индексируемого типа 3.6, определение личного типа 7.4, определение ссылочного типа 3,8, параметр подпрограммы 6.2, подпрограмма 6, понятие 3.1, процедура 6.1, предвыполнение не имеет другого эффекта 3.1, совмещение 6.6, 8.7, спецификация пакета 7.1, спецификация подпрограммы 6.1, список идентификаторов 3.2, статическое выражение 4.9, тип 3.3, указание подтипа 2, функция 6.5, экземпляр

1. ФОРМАЛЬНЫЕ ОБЪЕКТЫ НАСТРОЙКИ

Первая форма описания формального параметра настройки задает формальные объекты настройки. Тип формального объекта настройки — это базовый тип обозначения типа, данного в описании формального параметра настройки. Описание формального параметра настройки с несколькими идентификаторами эквивалентно последовательности единичных описаний, как поясняется в разд.

Формальный объект настройки имеет вид in или in out. При отсутствии в описании формального параметра настройки явного указания вида подразумевается вид in. Если описание формального параметра настройки задано выражением, то оно является выражением по умолчанию для этого формального параметра. Выражение по умолчанию допустимо только для параметров вида in (указанного либо явно, либо неявно). Тип выражения по умолчанию должен быть таким же, как и у соответствующего формального параметра настройки.

Формальный объект настройки вида in — это константа, значение которой является копией значения сопоставленного ему фактического параметра конкретизации настройки, как описано в разд. Тип формального объекта настройки вида in не должен быть лимитируемым типом; подтип 'такого формального объекта настройки — это подтип в обозначении типа, данного в описании параметра настройки.

Формальный объект настройки вида in out — это переменная, обозначающая объект, задаваемый в конкретизации настройки фактическим параметром настройки, как описано в разд. Ограничения, применяемые к формальному объекту настройки, те же, что и для соответствующего фактического параметра.

Примечание. Ограничения, применяемые к формальному объекту настройки вида in out, те же, что и для соответствующего фактического параметра (а не те, которые связаны с обозначением типа из описания параметра настройки). Во избежание путаницы рекомендуется, когда это возможно, использовать в описании такого формального объекта имя базового типа. Если, однако, базовый тип анонимный, то рекомендуется использовать имя подтипа, определенного в описании базового типа.

Ссылки: анонимный тип 1, базовый тип 3.3, вид 6.1, идентификатор 2.3, имя 4.1, конкретизация настройки 12.3, лимитируемый тип 4, обозначение типа 2, объект 3.3, ограничение 3.3, описание 3.1, описание константы 3.2, описание параметра настройки 12.1, описание типа 3.2, переменная 1, подтип 3.2, присваивание 5.2, простое имя 4.1, сопоставление фактического параметра настройки 12.3, фактический параметр настройки 12.3, формальный объект настройки 12.1, формальный параметр настройки

2. ФОРМАЛЬНЫЕ ТИПЫ НАСТРОЙКИ

Описание параметра настройки, включающее определение настраиваемого типа или описание личного типа, задает формальный тип настройки. Формальный тип настройки обозначает подтип, заданный соответствующим фактическим параметром в конкретизации настройки, как описано в п. г) разд. В настраиваемом модуле формальный тип настройки рассматривается как некоторый уникальный тип, отличный от всех остальных (формальных или нет) типов. Форма ограничения, применимого к формальному типу в указании подтипа, зависит от класса типа, как и для типов, не являющихся формальными.

В описании формального (ограниченного) индексируемого типа настройки в качестве формы дискретного диапазона допустимо только обозначение типа.

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

В описании и теле настраиваемого модуля операции, которые можно выполнять над значениями формального типа настройки (кроме дополнительных операций, заданных формальными подпрограммами настройки), определяются описанием параметра настройки для этого формального типа.

а) Для описания личного типа разрешены операции, определенные в разд. 2 (в частнос-|ти, для личного, но нелимитируемого типа — присваивание, равенство и неравенство).

б) Для определения индексируемого типа разрешены операции, определенные в разд. 2 (например, они включают формирование индексируемых компонент и отрезков).

в) Для определения ссылочного типа разрешены операции, определенные в разд. 2 (например, могут быть использованы генераторы).

Четыре формы определения настраиваемого типа, в которых содержится бокс (т.е. составной ограничитель о), соответствуют следующим основным формам скалярного типа:

г) Для дискретного типа: (о)

Разрешенные операции — общие для перечисленных и целых типов; они определены в разд. 5.

д) Для целого типа: range < >

Разрешенные операции над целыми типами определены в разд. 5.

е) Для плавающего типа: digits < >

Разрешенные операции определены в разд. 8.

ж) Для фиксированных типов; delta < >

Разрешенные операции определены в разд. 10.

Во всех случаях, пп. а) — е), каждая операция, неявно связанная с формальным типом (т.е. отличная от операции, заданной формальной подпрограммой), считается неявно описанной в месте описания формального типа. Это же относится и к формальному фиксированному типу, исключая мультипликативные операции, которые возвращают результат универсального-фиксированного типа (см. 5), так как эти специальные операции описаны в пакете STANDARD.

При конкретизации настройки каждая из этих операций — соответствующая базовая операция или предопределенная операция для сопоставленного фактического типа. Для операции это правило сохраняется даже в случае переопределения ее для фактического типа или некоторого его родительского типа.

Примеры формальных типов настройки:

type ITEM is private; type BUFFER(LENGTH : NATURAL) is limited private; type ENUM is <>; type INT is range <>; type ANGLE is delta <>; type MASS is digits <>; type TABLE is array (ENUM) of ITEM;

Пример раздела формальных параметров настройки с описанием формального целого типа:

generic type RANK Is range <>; FIRST : RANK := RANK'PIRST; SECOND : RANK :== FIRST + 1; — операция «+» для типа RANK

Ссылки: генератор 4.8, дискретный диапазон 3.6, дискретный тип 3.6, индексируемая компонента 1, класс типа 3.3, конкретизация 12.3, лимитируемый личный тип 4, мультипликативная операция 4.5, 5, неравенство 2, обозначение типа 2, ограничение 3.3, операция 4.5, операция типа 3.3, описание 3.1, описание настраиваемого модуля 12.1, описание параметра настройки 12.1, определение индексируемого типа 3.6, определение личного типа 7.4, определение настраиваемого типа 12.1, отрезок 2, перечислимый тип 1, плавающий тип 7, присваивание 5.2, равенство 2, раздел дискриминантов 1, раздел формальных параметров настройки 12.1, родительский тип 3.4, скалярный тип 3.5, сопоставление фактических параметров настройки 2, 3, 4, 5, стандартный пакет 8.6 С, тело настраиваемого модуля 12.2, указание подтипа 2, универсальный фиксированный тип 9, фактический тип настройки 12.3, фиксированный тип 9, формальная подпрограмма настройки 3, формальный тип настройки 12.1, целый тип 4.

3. ФОРМАЛЬНЫЕ ПОДПРОГРАММЫ НАСТРОЙКИ

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

В описании формальной подпрограммы настройки могут встречаться две формы умолчания. В них после спецификации подпрограммы следует зарезервированное слово is и либо бокс, либо имя подпрограммы или входа. Правила сопоставления для таких умолчаний описаны в разд. 12.3,6.

Формальная подпрограмма настройки обозначает подпрограмму, литерал перечисления или вход, заданный соответствующим фактическим параметром настройки в конкретизации настройки, как описано в разд. 6.

Примеры формальных подпрограмм настройки:

with function INCREASE(X : INTEGER) return INTEGER; with function SUM(X, Y : ITEM) return ITEM;with function "+"(X, Y : ITEM) return ITEM is <>; with function IMAGE(X : ENUM) return STRING is ENUM'IMAGE;with procedure UPDATE is DEFAULT_UPDATE;

Примечание. Ограничения на параметр формальной подпрограммы те же, что у соответствующего параметра в спецификации сопоставленной фактической подпрограммы (а не те, которые вводятся соответствующим обозначением типа в спецификации формальной подпрограммы). Это же относится и к результату функции. Во избежании путаницы рекомендуется везде, где можно, в описании формальной подпрограммы использовать имя базового типа, а не имя подтипа. Если, однако, базовый тип — анонимный, то рекомендуется использовать имя подтипа, определенное в описании типа.

Тип, заданный для формального параметра формальной подпрограммы настройки, может быть любым видимым типом, включая формальный тип настройки из того же раздела формальных параметров настройки.

Ссылки: анонимный тип 1, базовый тип 3.3, бокс 2, зарезервированное слово 2.9, знак операции 6.1, идентификатор 2.3, конкретизация настройки 12.3, область действия 8.2, обозначение 6.1, обозначение типа 3,2.2, ограничение 3.3, описание параметров настройки 12.1, описание переименования 8.5, описание подпрограммы 6.2, подпрограмма 6, подтип 2, сопоставление фактических подпрограмм настройки 6, спецификация подпрограммы 6.1, тип 3.3, фактический параметр настройки 12.3, формальная подпрограмма настройки 12.1, формальная функция настройки



Пример настраиваемого пакета


В следующем примере использован настраиваемый пакет для одной из возможных организаций стеков. Размер каждого стека и тип его элементов являются параметрами настройки.

generic SIZE : POSITIVE; type ITEM is private; package STACK is procedure PUSH (E : in ITEM); procedure POP (E : out ITEM); OVERFLOW, UNDERFLOW : exception;end STACK;package body STACK is type TABLE is array (POSITIVE range <>) of ITEM; SPACE : TABLE(1 .. SIZE); INDEX : NATURAL := 0; procedure PUSH(E : in ITEM) is begin if INDEX >= SIZE then raise OVERFLOW; end if; INDEX := INDEX + 1; SPACE(INDEX) := E; end PUSH;procedure POP(E : out ITEM) is begin if INDEX = 0 then raise UNDERFLOW; and if; E := SPACE(INDEX); INDEX := INDEX - 1: end POP;end STACK;

Экземпляры настраиваемого пакета могут быть получены так:

package STACK_INT is new STACK(SIZE => 200, ITEM => INTEGER);package STACK_BOOL is new STACK(100, BOOLEAN);

После этого могут быть вызваны процедуры конкретизированных пакетов:

STACK_INT.PUSH(N);STACK_BOOL.PUSH(TRUE);

Возможна другая организация стека (тело пакета опущено):

generic type ITEM is private; package ON_STACKS is type STACK(SIZE : POSITIVE) is limited private; procedure PUSH (S : in out STACK; E : in ITEM); procedure POP (S : in out STACK; E : out ITEM); OVERFLOW, UNDERFLOW : exception; private type TABLE is array (POSITIVE range <>) of ITEM; type STACK(SIZE : POSITIVE) is record SPACE : TABLE(1 .. SIZE); INDEX : NATURAL := 0; end record; end:

При использовании такого пакета сначала должна быть осуществлена конкретизация, после чего можно описать стеки с элементами соответствующего типа:

declare package STACK_REAL is new ON_STACKS(REAL); use STACK_REAL; S : STACK(100); begin ... PUSH(S, 2.54); ... end;