Параметры-типы
Не смотря на привлекательные свойства настраиваемых модулей, при определении характера задач, решаемых с помощью настраиваемого модуля, необходимо иметь возможность накладывать некоторые ограничения.
Допустим, что некоторые настраиваемые модули предусматривают возможность суммирования массива чисел.
Очевидно, что это характерно только для чисел, и мы не можем производить суммирование записей.
Следовательно, для того, чтобы защититься от конкретизации настраиваемых модулей с указанием не подходящих типов данных, требуется возможность в установке некоторых ограничений.
Кроме того, желательно чтобы компилятор также мог осуществлять проверку того, что мы не выполняем какие-нибудь не допустимые действия с переменной внутри кода настраиваемого модуля, например, чтобы он не разрешал использовать атрибут 'Pred для записей.
Решение таких задач обеспечивается механизмом который основан на виде спецификации формального параметра-типа.
Таким образом, спецификация формального параметра-типа определяет категорию типов, которые могут быть использованы при конкретизации настраиваемого модуля, а также те действия, которые можно осуществлять над формальным параметром внутри настраиваемого модуля.
Ниже показан общий список вариантов спецификаций формальных параметров-типов и различные ограничения, накладываемые на выбор фактических параметров-типов настраиваемых модулей.
type T is limited private -- тип T - любой тип type T is private -- тип T - любой не лимитированный тип
type T is (<>) -- тип T любой дискретный тип -- (целочисленный или перечислимый) type T is range <> -- тип T любой целочисленный тип type T is mod <> -- тип T любой модульный целочисленный тип type T is digits <> -- тип T любой вещественный тип с плавающей точкой type T is delta <> -- тип T любой вещественный тип с фиксированной точкой type T is delta <> digits <> -- тип T любой вещественный децимальный тип type T is access Y; -- тип T любой ссылающийся на Y ссылочный тип type T is access all Y; -- тип T любой "access all Y" ссылочный тип type T is access constant Y; -- тип T любой "access constant Y" ссылочный тип -- примечание: тип Y может быть предварительно описанным -- настраиваемым параметром type T is array(Y range <>) of Z; -- тип T любой неограниченный массив элементов типа Z -- у которого Y - подтип индекса type T is array(Y) of Z; -- тип T любой ограниченный массив элементов типа Z -- у которого Y - подтип индекса -- примечание: тип Z (тип компонента фактического массива) -- должен совпадать с типом формального массива. -- если они не являются скалярными типами, -- то они оба должны иметь тип -- ограниченного или неограниченного массива type T is new Y; -- тип T любой производный от Y тип type T is new Y with private; -- тип T любой не абстрактный тэговый тип -- производный от Y type T is abstract new Y with private; -- тип T любой тэговый тип производный от Y type T is tagged private; -- тип T любой не абстрактный не лимитированый -- тэговый тип type T is tagged limited private; -- тип T любой не абстрактный тэговый тип type T is abstract tagged private; -- тип T любой не лимитированый тэговый тип type T is abstract tagged limited private; -- тип T любой тэговый тип |
Для того чтобы лучше понять правила управляющие конкретизацией для параметров типа массив, рассмотрим следующий настраиваемый пакет:
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 . . . |
и типы:
type Color is (red, green, blue); type Mix is array (Color range <> ) of Boolean; type Option is array (Color) of Boolean; |
тогда, Mix может соответствовать Vector, а Option может соответствовать Table.
package R is new P( Item => Boolean, Index => Color, Vector => Mix, Table => Option); |