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

4.10 Атрибуты изображений

Изображение значения — это строка, представляющая значение в виде для отображения. Атрибуты Image, Wide_Image и Wide_Wide_Image доступны для получения изображения значения в виде String, Wide_String или Wide_Wide_String (соответственно). Пользовательские изображения для данного типа могут быть реализованы путём переопределения стандартной реализации атрибута Put_Image.

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

Для каждого подтипа S типа T, отличного от universal_real или universal_fixed, определён следующий операционный атрибут, связанный с типом:
S'Put_Image
S'Put_Image обозначает процедуру со следующим описанием:
procedure S'Put_Image
(Буфер : in out
Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
Аргумент : in T);
Стандартная реализация S'Put_Image записывает (используя Wide_Wide_Put) изображение значения Аргумент.
Атрибут Put_Image может быть задан для любого конкретного типа T либо посредством определения_атрибута, либо путём указание_аспекта, задающего аспект Put_Image для типа. Аспект Put_Image не наследуется, а для производных типов он неявно составлен, как определено ниже.
Для указания_аспекта или определения_атрибута, задающих Put_Image, подтип параметра Аргумент должен быть первым подтипом или базовым подтипом, если скалярный, и первым подтипом, если не скалярный.
Поведение стандартной реализации S'Put_Image зависит от класса T.
Для неотомеченного производного типа или нулевого расширения стандартная реализация T'Put_Image вызывает Put_Image для родительского типа по преобразованию параметра типа T к родительскому типу.
Для непроизводного элементарного типа реализация эквивалентна:
procedure Scalar_Type'Put_Image
(Буфер : in out Ada.Strings.Text_Buffers.Root_Buffer_Type'Class;
Аргумент : in Scalar_Type) is
begin
Буфер.Wide_Wide_Put (<описано ниже>);
end Scalar_Type'Put_Image;
где значение Wide_Wide_String, выводимое в буфер текста, определяется следующим образом:
  • Для целочисленного типа выводимое изображение — соответствующая десятичная литеральная запись без нижних подчеркиваний, ведущих нулей, экспоненты или trailing spaces, но с одним ведущим знаком, который либо минус, либо пробел.
  • Для перечислимого типа выводимое изображение — либо соответствующий идентификатор в верхнем регистре, либо соответствующая символьная литеральная запись (включая два апострофа); ни ведущие, ни trailing spaces не включаются. Для неграфического символа (значения типа символа, у которого нет связанного с ним перечислимого литерала), значение — соответствующее определяемое языком имя в верхнем регистре (например, изображение неграфического символа, идентифицированного как nul, равно "NUL" — кавычки не входят в изображение).
  • Для типа с плавающей точкой выводимое изображение — десятичная вещественная литеральная запись, наилучшим образом приближающая значение (округляя от нуля, если ровно посередине) с одним ведущим знаком, который либо минус, либо пробел, одной цифрой (не равной нулю, если значение не равно нулю), десятичной точкой, S'Digits-1 (см. 3.5.8) цифрами после десятичной точки (но одной, если S'Digits равен единице), заглавной буквой E, знаком экспоненты (либо + либо -) и двумя или более цифрами (с ведущими нулями, если необходимо), представляющими экспоненту. Если S'Signed_Zeros равен True, то ведущий знак — минус для отрицательно знакового нуля.
  • Для типа с фиксированной точкой выводимое изображение — десятичная вещественная литеральная запись, наилучшим образом приближающая значение (округляя от нуля, если ровно посередине) с одним ведущим знаком, который либо минус, либо пробел, одной или более цифрами перед десятичной точкой (без лишних ведущих нулей), десятичной точкой и S'Aft (см. 3.5.10) цифрами после десятичной точки.
  • Для типа доступа (именованного или безымянного) выводимое изображение зависит от того, является ли значение null. Если оно null, то изображение равно "NULL". В противном случае изображение — левая круглая скобка, за которой следует "ACCESS", пробел и последовательность графических символов, отличных от пробела или правой круглой скобки, представляющих местоположение обозначенного объекта, за которой следует правая круглая скобка, например, "(ACCESS FF0012AC)".
Для непустого расширения типа стандартная реализация T'Put_Image зависит от существования неинтерфейсного предка T (кроме самого T), для которого аспект Put_Image задан напрямую. Если такой предок существует, то T'Put_Image сгенерирует изображение, основанное на синтаксисе агрегата расширения, где тип предка агрегата расширения — ближайший тип предка, для которого задан аспект Put_Image. Если такого предка нет, то стандартная реализация T'Put_Image совпадает с описанной ниже реализацией для непроизводного типа записи.
Для конкретного, непроизводного составного типа:
  • Если стандартная реализация Put_Image записывает компоненты, порядок записи компонентов совпадает с каноническим порядком, в котором компоненты составного типа T записываются стандартной реализацией T'Write. Этот порядок также используется для определения смысла позиционного агрегата типа T.
  • Для типа массива T стандартная реализация T'Put_Image генерирует изображение на основе синтаксиса именованного (не позиционного) агрегата массива (с '[' и ']' в качестве разделителей) с использованием вызовов процедур Put_Image типа(ов) индекса и типа элемента для генерации изображений значений этих типов.
Случай нулевого массива обрабатывается особым образом, используя диапазоны для границ индексов и "<>" как синтаксического заменителя значения компонента.
  • Для типа записи (или, как указано выше, типа расширения без неинтерфейсного предка, задающего Put_Image) или защищённого типа стандартная реализация T'Put_Image генерирует изображение на основе синтаксиса именованного (не позиционного) агрегата записи (за исключением того, что для защищённого типа начальная левая круглая скобка сопровождается "PROTECTED with "). Имена компонентов отображаются в верхнем регистре, следуя правилам для изображения значения перечислимого типа. Значения компонентов отображаются путём вызовов процедуры Put_Image типа компонента.
Изображение, выводимое для записи без компонентов (включая любой интерфейсный тип), равно "(NULL RECORD)". Изображение, выводимое для защищённого типа без компонентов, равно "(PROTECTED NULL RECORD)". В случае защищённого типа T вызов стандартной реализации T'Put_Image запускает только один защищённый (только для чтения) action.
  • Для типа задачи без дискриминаторов стандартная реализация T'Put_Image генерирует изображение вида "(TASK <task_id_image>)", где <task_id_image> — результат, полученный путём вызова Task_Identification.Image с id заданной задачи, а затем передачей этой строки в Characters.Conversions.To_Wide_Wide_String.
  • Для типа задачи с дискриминаторами стандартная реализация T'Put_Image также включает значения дискриминаторов, например:
"(TASK <task_id_image> with D1 => 123, D2 => 456)"
Для типа всего класса стандартная реализация T'Put_Image генерирует изображение на основе синтаксиса квалифицированного выражения. Wide_Wide_Put вызывается с Wide_Wide_Expanded_Name of Arg'Tag. Затем S'Put_Image вызывается, где S — конкретный тип, определённый Arg'Tag.
T'Put_Image одинаков как для частичного, так и для полного представления T, если T имеет частичное представление.
В профиле_параметра_и_результата для стандартной реализации Put_Image подтип параметра Аргумент — базовый подтип T, если T — скалярный тип, и первый подтип в противном случае. Для указания_аспекта или определения_атрибута, задающих Put_Image, имя подпрограммы должно обозначать неабстрактную процедуру, второй параметр которой — либо первый подтип T, либо, как вариант, при T скалярном, базовый подтип T.
Для каждого подтипа S типа T определены следующие атрибуты:
S'Wide_Wide_Image

S'Wide_Wide_Image обозначает функцию со следующим описанием:
function S'Wide_Wide_Image(Аргумент : S'Base)
return Wide_Wide_String
S'Wide_Wide_Image вызывает S'Put_Image, передавая Аргумент (который обычно хранит последовательность значений символов в буфере текста), а затем возвращает результат извлечения содержимого этого буфера с помощью функции Wide_Wide_Get. Нижняя граница результата — единица. Любое исключение, распространяемое вызовом S'Put_Image, распространяется.
S'Wide_Image
S'Wide_Image обозначает функцию со следующим описанием:
function S'Wide_Image(Аргумент : S'Base)
return Wide_String
S'Wide_Image вызывает S'Put_Image, передавая Аргумент (который обычно хранит последовательность значений символов в буфере текста), а затем возвращает результат извлечения содержимого этого буфера с помощью функции Wide_Get. Нижняя граница результата — единица. Любое исключение, распространяемое вызовом S'Put_Image, распространяется.
S'Image
S'Image обозначает функцию со следующим описанием:
function S'Image(Аргумент : S'Base)
return String
Вызов S'Put_Image передаёт Arg (в котором обычно хранится последовательность символьных значений в буфере текста) и возвращает результат извлечения содержимого этого буфера с помощью функции Get. Нижний предел результата равен единице. Любое исключение, переданное вызовом S'Put_Image, передаётся дальше.
Для префикса X типа T, отличного от universal_real или universal_fixed, определены следующие атрибуты:
X'Wide_Wide_Image

X'Wide_Wide_Image обозначает результат вызова функции S'Wide_Wide_Image с Arg, равным X, где S — номинальный подтип X.
X'Wide_Image
X'Wide_Image обозначает результат вызова функции S'Wide_Image с Arg, равным X, где S — номинальный подтип X.
X'Image
X'Image обозначает результат вызова функции S'Image с Arg, равным X, где S — номинальный подтип X.

Разрешения реализации

Реализация может преобразовывать изображение, сгенерированное по умолчанию реализацией S'Put_Image для составного подтипа S следующим образом:
  • Если S — составной подтип, а ведущий символ изображения M значения компонента или индекса — пробел, а непосредственно перед ним (если есть) — открывающая скобка, открытая квадратная скобка или пробел, то ведущий пробел изображения M может быть опущен.
  • Если S — подтип массива, а нижняя граница массива в каждом измерении равна нижней границе соответствующего подтипа индекса, и значение массива не является пустым значением массива, то может использоваться синтаксис позиционных агрегатов массива.
  • Если S — подтип массива и данное значение может быть отображено с использованием синтаксиса named_array_aggregate, где некоторый discrete_choice_list определяет более одного значения индекса, определяя последовательность одного или нескольких диапазонов и значений, разделенных вертикальными чертами, то это изображение может быть сгенерировано вместо него; это может включать перестановку значений компонентов.
  • Аналогично, если S — подтип записи (или дискриминируемого типа), и данное значение может быть отображено с использованием синтаксиса именованной ассоциации компонентов, где длина некоторого component_choice_list больше единицы, то это изображение может быть сгенерировано вместо него; это может включать перестановку значений компонентов.
  • Дополнительные пробелы (Wide_Wide_Characters с позицией 32) и вызовы операции New_Line буфера текста могут быть вставлены для улучшения удобочитаемости сгенерированного изображения, причём пробелы вставляются непосредственно или через использование процедур Increase_Indent и Decrease_Indent.
  • Для типа строки реализации могут создавать изображение, соответствующее строковой литерале.
  • Для типа объединения без проверки реализации могут возбудить Program_Error или создать какое-то узнаваемое изображение (например, "(UNCHECKED UNION)"), которое не требует чтения дискриминантов.
Для каждого определённого языком нескалярного типа T может быть задан T'Put_Image.

Требования к реализации

Для каждого определённого языком контейнерного типа T (то есть каждого из типов Vector, List, Map, Set, Tree и Holder, определённых в различных дочерних элементах Ada.Containers), T'Put_Image должен быть задан так, чтобы T'Image производил результат, совместимый с синтаксисом агрегата массива (с использованием '[' и ']' в качестве разделителей) следующим образом:
  • Изображения Vector должны быть совместимы с изображением по умолчанию типа массива с теми же типами индексов и компонентов.
  • Изображения Map должны быть совместимы с синтаксисом именованного агрегата массива, используя изображения значений ключей вместо имён дискретного выбора. Например, [Key1 => Value1, Key2 => Value2].
  • Изображения Set, List и Holder должны быть совместимы с синтаксисом позиционного агрегата массива. Элементы List должны появляться в порядке в изображении списка. Изображение пустого держателя должно быть [].
  • Изображения Tree (и изображения поддеревьев деревьев) должны быть совместимы с синтаксисом позиционного агрегата массива. Например, [[1, 2], [111, 222, 333]].
Для каждого определённого языком нескалярного типа T, имеющего примитивную языковую функцию Image, профиль которой совместим с профилем T'Image (например, Ada.Numerics.Float_Random.State имеет такую функцию Image), T'Put_Image должен быть задан так, чтобы T'Image давал тот же результат, что и эта функция Image.

Рекомендации по реализации

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


Spec-Zone.ru

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