Справочник по Ada (Ada 2022)
A.18.4 Карты
Определяемые языком обобщенные пакеты Containers.Hashed_Maps и Containers.Ordered_Maps предоставляют частные типы Map и Cursor, а также набор операций для каждого типа. Контейнер карты позволяет использовать произвольный тип в качестве ключа для поиска элемента, связанного с этим ключом. Хэшированная карта использует хеш-функцию для организации ключей, а упорядоченная карта упорядочивает ключи в соответствии с заданным отношением.
Этот подпункт описывает объявления, общие для обоих видов карт. См. A.18.5 для описания семантики, специфичной для Containers.Hashed_Maps, и A.18.6 для описания семантики, специфичной для Containers.Ordered_Maps.
Статическая семантика
Ожидается, что фактическая функция для обобщенного формального оператора «=» для значений Element_Type определит рефлексивное и симметричное отношение и вернёт одно и то же значение результата каждый раз, когда она вызывается с определённой парой значений. Если она ведет себя каким-либо другим образом, оператор «=» для значений карты возвращает неопределённое значение. Точные аргументы и количество вызовов этой обобщенной формальной функции оператором «=» для значений карты не определены.
Тип Map используется для представления карт. Тип Map требует финализации (см. 7.6).
Карта содержит пары ключей и элементов, называемые узлами. Курсоры карт обозначают узлы, но также могут рассматриваться как обозначающие элемент (элемент, содержащийся в узле) для согласованности с другими контейнерами. Существует отношение эквивалентности для ключей, определение которого различается для хэшированных карт и упорядоченных карт. Карта никогда не содержит два или более узлов с эквивалентными ключами. Длина карты — это количество узлов, которые она содержит.
Каждая непустая карта имеет два особых узла, называемые первым узлом и последним узлом (которые могут быть одинаковыми). Каждый узел, кроме последнего, имеет последующий узел. Если не было других промежуточных операций, начиная с первого узла и многократно переходя к последующему узлу, каждый узел в карте будет посещён ровно один раз до тех пор, пока не будет достигнут последний узел. Точное определение этих терминов отличается для хэшированных и упорядоченных карт.
Некоторые операции проверяют «вмешательство с курсорами» контейнера, так как они зависят от того, что множество элементов контейнера остаётся неизменным, а другие проверяют «вмешательство с элементами» контейнера, так как они зависят от того, что элементы контейнера не заменяются. Когда вмешательство с курсорами запрещено для конкретного объекта карты M, Program_Error распространяется при финализации M, а также при вызове, передающем M в некоторые операции этого пакета, как указано в предопределении такой операции. Аналогично, когда вмешательство с элементами запрещено для M, Program_Error распространяется при вызове, передающем M в некоторые другие операции этого пакета, как указано в предопределении такой операции.
Абзацы с 8 по 15 удалены, так как теперь эти правила описаны в предопределениях.
Empty_Map представляет собой пустой объект Map. Его длина равна 0. Если объект типа Map не инициализирован иначе, он инициализируется тем же значением, что и Empty_Map.
No_Element представляет собой курсор, который не обозначает ни одного узла. Если объект типа Cursor не инициализирован иначе, он инициализируется тем же значением, что и No_Element.
Примитивный оператор «=» для типа Cursor возвращает True, если оба курсора являются No_Element или обозначают один и тот же элемент в одном и том же контейнере.
Выполнение стандартной реализации атрибутов Input, Output, Read или Write для типа Cursor вызывает исключение Program_Error.
Map'Write для объекта карты M записывает Length(M) элементов карты в поток. Он также может записать дополнительную информацию о карте.
Map'Read считывает представление карты из потока и присваивает Item карте с той же длиной и теми же элементами, что и записанные Map'Write.
function Has_Element (Position : Cursor) return Boolean
with Nonblocking, Global => in all, Use_Formal => null;
with Nonblocking, Global => in all, Use_Formal => null;
Возвращает True, если Position обозначает элемент, и False в противном случае.
function Has_Element (Container : Map; Position : Cursor)
return Boolean
with Nonblocking, Global => null, Use_Formal => null;
return Boolean
with Nonblocking, Global => null, Use_Formal => null;
Возвращает True, если Position обозначает элемент в Container, и False в противном случае.
function "=" (Left, Right : Map) return Boolean;
Если Left и Right обозначают один и тот же объект карты, функция возвращает True. Если Left и Right имеют разную длину, функция возвращает False. В противном случае для каждого ключа K в Left функция возвращает False, если:
ключ, эквивалентный K, отсутствует в Right; или
элемент, связанный с K в Left, не равен элементу, связанному с K в Right (используя обобщенный формальный оператор равенства для элементов).
Если функция не вернула результат после проверки всех ключей, она возвращает True. Любое исключение, возникшее во время вычисления эквивалентности ключей или равенства элементов, распространяется.
function Tampering_With_Cursors_Prohibited
(Container : Map) return Boolean
with Nonblocking, Global => null, Use_Formal => null;
(Container : Map) return Boolean
with Nonblocking, Global => null, Use_Formal => null;
Возвращает True, если вмешательство с курсорами или вмешательство с элементами в данный момент запрещено для Container, и False в противном случае.
function Tampering_With_Elements_Prohibited
(Container : Map) return Boolean
with Nonblocking, Global => null, Use_Formal => null;
(Container : Map) return Boolean
with Nonblocking, Global => null, Use_Formal => null;
Всегда возвращает False, независимо от того, запрещено ли вмешательство с элементами.
function Length (Container : Map) return Count_Type
with Nonblocking, Global => null, Use_Formal => null;
with Nonblocking, Global => null, Use_Formal => null;
Возвращает количество узлов в Container.
function Is_Empty (Container : Map) return Boolean
with Nonblocking, Global => null, Use_Formal => null,
Post => Is_Empty'Result = (Length (Container) = 0);
with Nonblocking, Global => null, Use_Formal => null,
Post => Is_Empty'Result = (Length (Container) = 0);
Возвращает True, если Container пуста.
procedure Clear (Container : in out Map)
with Pre => not Tampering_With_Cursors_Prohibited (Container)
or else raise Program_Error,
Post => Length (Container) = 0;
with Pre => not Tampering_With_Cursors_Prohibited (Container)
or else raise Program_Error,
Post => Length (Container) = 0;
Удаляет все узлы из Container.
function Key (Position : Cursor) return Key_Type
with Pre => Position /= No_Element
or else raise Constraint_Error,
Nonblocking, Global => in all, Use_Formal => Key_Type;
with Pre => Position /= No_Element
or else raise Constraint_Error,
Nonblocking, Global => in all, Use_Formal => Key_Type;
Key возвращает компонент ключа узла, обозначенного Position.
function Key (Container : Map;
Position : Cursor) return Key_Type
with Pre => (Position /= No_Element
or else raise Constraint_Error) and then
(Has_Element (Container, Position)
or else raise Program_Error),
Nonblocking, Global => null, Use_Formal => Key_Type;
Position : Cursor) return Key_Type
with Pre => (Position /= No_Element
or else raise Constraint_Error) and then
(Has_Element (Container, Position)
or else raise Program_Error),
Nonblocking, Global => null, Use_Formal => Key_Type;
Key возвращает компонент ключа узла, обозначенного Position.
function Element (Position : Cursor) return Element_Type
with Pre => Position /= No_Element
or else raise Constraint_Error,
Nonblocking, Global => in all, Use_Formal => Element_Type;
with Pre => Position /= No_Element
or else raise Constraint_Error,
Nonblocking, Global => in all, Use_Formal => Element_Type;
Element возвращает компонент элемента узла, обозначенного Position.
function Element (Container : Map;
Position : Cursor) return Element_Type
with Pre => (Position /= No_Element
or else raise Constraint_Error) and then
(Has_Element (Container, Position)
or else raise Program_Error),
Nonblocking, Global => null, Use_Formal => Element_Type;
Position : Cursor) return Element_Type
with Pre => (Position /= No_Element
or else raise Constraint_Error) and then
(Has_Element (Container, Position)
or else raise Program_Error),
Nonblocking, Global => null, Use_Formal => Element_Type;
Element возвращает компонент элемента узла, обозначенного Position.
procedure Replace_Element (Container : in out Map;
Position : in Cursor;
New_item : in Element_Type)
with Pre => (not Tampering_With_Elements_Prohibited (Container)
or else raise Program_Error) and then
(Position /= No_Element
or else raise Constraint_Error) and then
(Has_Element (Container, Position)
or else raise Program_Error);
Position : in Cursor;
New_item : in Element_Type)
with Pre => (not Tampering_With_Elements_Prohibited (Container)
or else raise Program_Error) and then
(Position /= No_Element
or else raise Constraint_Error) and then
(Has_Element (Container, Position)
or else raise Program_Error);
Replace_Element присваивает New_Item элементу узла, обозначенного Position. В целях определения перекрытия параметров в вызове Replace_Element параметр Container не считается перекрывающимся ни с каким объектом (в том числе и с самим собой).
procedure Query_Element
(Position : in Cursor;
Process : not null access procedure (Key : in Key_Type;
Element : in Element_Type))
with Pre => Position /= No_Element
or else raise Constraint_Error,
Global => in all;
(Position : in Cursor;
Process : not null access procedure (Key : in Key_Type;
Element : in Element_Type))
with Pre => Position /= No_Element
or else raise Constraint_Error,
Global => in all;
Query_Element вызывает Process.all с ключом и элементом из узла, обозначенного Position, в качестве аргументов. Вмешательство с элементами карты, содержащей элемент, обозначенный Position, запрещено во время выполнения вызова Process.all. Любое исключение, поднятое Process.all, распространяется.
процедура Query_Element
(Container : вход Map;
Position : вход Cursor;
Process : не null доступная процедура (Key : вход Key_Type;
Element : вход Element_Type))
с Pre => (Position /= No_Element
или else поднять Constraint_Error) и затем
(Has_Element (Container, Position)
или else поднять Program_Error);
(Container : вход Map;
Position : вход Cursor;
Process : не null доступная процедура (Key : вход Key_Type;
Element : вход Element_Type))
с Pre => (Position /= No_Element
или else поднять Constraint_Error) и затем
(Has_Element (Container, Position)
или else поднять Program_Error);
Query_Element вызывает Process.all с ключом и элементом из узла, обозначенного Position, в качестве аргументов. Изменение элементов Container запрещено во время выполнения вызова Process.all. Любое исключение, поднятое Process.all, распространяется.
процедура Update_Element
(Container : вход-выход Map;
Position : вход Cursor;
Process : не null доступная процедура (Key : вход Key_Type;
Element : вход-выход Element_Type))
с Pre => (Position /= No_Element
или else поднять Constraint_Error) и затем
(Has_Element (Container, Position)
или else поднять Program_Error);
(Container : вход-выход Map;
Position : вход Cursor;
Process : не null доступная процедура (Key : вход Key_Type;
Element : вход-выход Element_Type))
с Pre => (Position /= No_Element
или else поднять Constraint_Error) и затем
(Has_Element (Container, Position)
или else поднять Program_Error);
Update_Element вызывает Process.all с ключом и элементом из узла, обозначенного Position, в качестве аргументов. Изменение элементов Container запрещено во время выполнения вызова Process.all. Любое исключение, поднятое Process.all, распространяется.
Если Element_Type не ограничен и определен, то фактический параметр Element в Process.all должен быть не ограничен.
тип Constant_Reference_Type
(Element : не null доступная константа Element_Type) is private
с Implicit_Dereference => Element,
Nonblocking, Global =>вход-выход синхронизирован,
Default_Initial_Condition => (поднять Program_Error);
(Element : не null доступная константа Element_Type) is private
с Implicit_Dereference => Element,
Nonblocking, Global =>вход-выход синхронизирован,
Default_Initial_Condition => (поднять Program_Error);
тип Reference_Type (Element : не null доступная Element_Type) is private
с Implicit_Dereference => Element,
Nonblocking, Global => вход-выход синхронизирован,
Default_Initial_Condition => (поднять Program_Error);
с Implicit_Dereference => Element,
Nonblocking, Global => вход-выход синхронизирован,
Default_Initial_Condition => (поднять Program_Error);
Типы Constant_Reference_Type и Reference_Type нуждаются в завершении.
Этот абзац был удален.
функция Constant_Reference (Container : ссылочный вход Map;
Position : вход Cursor)
возвращает Constant_Reference_Type
с Pre => (Position /= No_Element
или else поднять Constraint_Error) и затем
(Has_Element (Container, Position)
или else поднять Program_Error),
Post => Tampering_With_Cursors_Prohibited (Container),
Nonblocking, Global => null, Use_Formal => null;
Position : вход Cursor)
возвращает Constant_Reference_Type
с Pre => (Position /= No_Element
или else поднять Constraint_Error) и затем
(Has_Element (Container, Position)
или else поднять Program_Error),
Post => Tampering_With_Cursors_Prohibited (Container),
Nonblocking, Global => null, Use_Formal => null;
Эта функция (в сочетании с аспектами Constant_Indexing и Implicit_Dereference) предоставляет удобный способ получения чтения доступа к отдельному элементу Map, заданного указателем.
Constant_Reference возвращает объект, дискриминант которого представляет собой доступную ссылку, обозначающую элемент, обозначенный Position. Изменение элементов Container запрещено, пока существует возвращенный объектом Constant_Reference и он не был завершен.
функция Reference (Container : ссылочный вход-выход Map;
Position : вход Cursor)
возвращает Reference_Type
с Pre => (Position /= No_Element
или else поднять Constraint_Error) и затем
(Has_Element (Container, Position)
или else поднять Program_Error),
Post => Tampering_With_Cursors_Prohibited (Container),
Nonblocking, Global => null, Use_Formal => null;
Position : вход Cursor)
возвращает Reference_Type
с Pre => (Position /= No_Element
или else поднять Constraint_Error) и затем
(Has_Element (Container, Position)
или else поднять Program_Error),
Post => Tampering_With_Cursors_Prohibited (Container),
Nonblocking, Global => null, Use_Formal => null;
Эта функция (в сочетании с аспектами Variable_Indexing и Implicit_Dereference) предоставляет удобный способ получения чтения и записи доступа к отдельному элементу Map, заданного указателем.
Reference возвращает объект, дискриминант которого представляет собой доступную ссылку, обозначающую элемент, обозначенный Position. Изменение элементов Container запрещено, пока существует возвращенный объектом Reference и он не был завершен.
функция Constant_Reference (Container : ссылочный вход Map;
Key : вход Key_Type)
возвращает Constant_Reference_Type
с Pre => Find (Container, Key) /= No_Element
или else поднять Constraint_Error,
Post => Tampering_With_Cursors_Prohibited (Container),
Nonblocking, Global => null, Use_Formal => null;
Key : вход Key_Type)
возвращает Constant_Reference_Type
с Pre => Find (Container, Key) /= No_Element
или else поднять Constraint_Error,
Post => Tampering_With_Cursors_Prohibited (Container),
Nonblocking, Global => null, Use_Formal => null;
Эта функция (в сочетании с аспектами Constant_Indexing и Implicit_Dereference) предоставляет удобный способ получения чтения доступа к отдельному элементу карты, заданному значением ключа.
Эквивалентно Constant_Reference (Container, Find (Container, Key)).
функция Reference (Container : ссылочный вход-выход Map;
Key : вход Key_Type)
возвращает Reference_Type
с Pre => Find (Container, Key) /= No_Element
или else поднять Constraint_Error,
Post => Tampering_With_Cursors_Prohibited (Container),
Nonblocking, Global => null, Use_Formal => null;
Key : вход Key_Type)
возвращает Reference_Type
с Pre => Find (Container, Key) /= No_Element
или else поднять Constraint_Error,
Post => Tampering_With_Cursors_Prohibited (Container),
Nonblocking, Global => null, Use_Formal => null;
Эта функция (в сочетании с аспектами Variable_Indexing и Implicit_Dereference) предоставляет удобный способ получения чтения и записи доступа к отдельному элементу карты, заданному значением ключа.
Эквивалентно Reference (Container, Find (Container, Key)).
процедура Assign (Target : вход-выход Map; Source : вход Map)
с Pre => не Tampering_With_Cursors_Prohibited (Target)
или else поднять Program_Error,
Post => Length (Source) = Length (Target);
с Pre => не Tampering_With_Cursors_Prohibited (Target)
или else поднять Program_Error,
Post => Length (Source) = Length (Target);
Если Target обозначает тот же объект, что и Source, операция не имеет эффекта. В противном случае пары ключ/элемент из Source копируются в Target, как при операторе присваивания Source в Target.
процедура Move (Target : вход-выход Map;
Source : вход-выход Map)
с Pre => (не Tampering_With_Cursors_Prohibited (Target)
или else поднять Program_Error) и затем
(не Tampering_With_Cursors_Prohibited (Source)
или else поднять Program_Error),
Post => (если не Target'Has_Same_Storage (Source) то
Length (Target) = Length (Source'Old) и затем
Length (Source) = 0);
Source : вход-выход Map)
с Pre => (не Tampering_With_Cursors_Prohibited (Target)
или else поднять Program_Error) и затем
(не Tampering_With_Cursors_Prohibited (Source)
или else поднять Program_Error),
Post => (если не Target'Has_Same_Storage (Source) то
Length (Target) = Length (Source'Old) и затем
Length (Source) = 0);
Если Target обозначает тот же объект, что и Source, то операция не имеет эффекта. В противном случае операция эквивалентна Assign (Target, Source) и затем Clear (Source).
процедура Insert (Container : вход-выход Map;
Key : вход Key_Type;
New_Item : вход Element_Type;
Position : выход Cursor;
Inserted : выход Boolean)
с Pre => (не Tampering_With_Cursors_Prohibited (Container)
или else поднять Program_Error) и затем
(Length (Container) <= Count_Type'Last - 1
или else поднять Constraint_Error),
Post => (объявить
Original_Length : константа Count_Type :=
Length (Container)'Old;
начать
Has_Element (Container, Position) и затем
(если Inserted то
Length (Container) = Original_Length + 1
иначе
Length (Container) = Original_Length));
Key : вход Key_Type;
New_Item : вход Element_Type;
Position : выход Cursor;
Inserted : выход Boolean)
с Pre => (не Tampering_With_Cursors_Prohibited (Container)
или else поднять Program_Error) и затем
(Length (Container) <= Count_Type'Last - 1
или else поднять Constraint_Error),
Post => (объявить
Original_Length : константа Count_Type :=
Length (Container)'Old;
начать
Has_Element (Container, Position) и затем
(если Inserted то
Length (Container) = Original_Length + 1
иначе
Length (Container) = Original_Length));
Insert проверяет, присутствует ли в Container узел с ключом, эквивалентным Key. Если совпадение найдено, Inserted устанавливается в False, и Position обозначает элемент с совпадающим ключом. В противном случае Insert выделяет новый узел, инициализирует его Key и New_Item и добавляет его в Container; Inserted устанавливается в True, и Position обозначает вновь вставленный узел. Любое исключение, поднятое во время выделения, распространяется, и Container не изменяется.
Замена проверяет, присутствует ли в контейнере узел с ключом, эквивалентным ключу. Если совпадение найдено, Замена присваивает ключу и Новому_Элементу соответствующий узел; в противном случае возникает Constraint_Error.
процедура Exclude (Container : вход-выход Map;
Key : вход Key_Type)
с Pre => не Tampering_With_Cursors_Prohibited (Container)
иначе повысить Program_Error,
Post => (объявить
Original_Length : константа Count_Type :=
Length (Container)'Old;
начать
Length (Container)
в Original_Length - 1 | Original_Length);
Key : вход Key_Type)
с Pre => не Tampering_With_Cursors_Prohibited (Container)
иначе повысить Program_Error,
Post => (объявить
Original_Length : константа Count_Type :=
Length (Container)'Old;
начать
Length (Container)
в Original_Length - 1 | Original_Length);
Exclude проверяет, присутствует ли в Container узел с ключом, эквивалентным Key. Если совпадение найдено, Exclude удаляет узел из карты.
процедура Delete (Container : вход-выход Map;
Key : вход Key_Type)
с Pre => не Tampering_With_Cursors_Prohibited (Container)
иначе повысить Program_Error,
Post => Length (Container) = Length (Container)'Old - 1;
Key : вход Key_Type)
с Pre => не Tampering_With_Cursors_Prohibited (Container)
иначе повысить Program_Error,
Post => Length (Container) = Length (Container)'Old - 1;
Delete проверяет, присутствует ли в Container узел с ключом, эквивалентным Key. Если совпадение найдено, Delete удаляет узел из карты; в противном случае возникает Constraint_Error.
процедура Delete (Container : вход-выход Map;
Position : вход-выход Cursor)
с Pre => (не Tampering_With_Cursors_Prohibited (Container)
иначе повысить Program_Error) и затем
(Position /= No_Element
иначе повысить Constraint_Error) и затем
(Has_Element (Container, Position)
иначе повысить Program_Error),
Post => Length (Container) = Length (Container)'Old - 1 и затем
Position = No_Element;
Position : вход-выход Cursor)
с Pre => (не Tampering_With_Cursors_Prohibited (Container)
иначе повысить Program_Error) и затем
(Position /= No_Element
иначе повысить Constraint_Error) и затем
(Has_Element (Container, Position)
иначе повысить Program_Error),
Post => Length (Container) = Length (Container)'Old - 1 и затем
Position = No_Element;
Delete удаляет узел, обозначенный Position, из карты.
функция First (Container : Map) возвращает Cursor
с Nonblocking, Global => null, Use_Formal => null,
Post => (если не Is_Empty (Container)
то Has_Element (Container, First'Result)
иначе First'Result = No_Element);
с Nonblocking, Global => null, Use_Formal => null,
Post => (если не Is_Empty (Container)
то Has_Element (Container, First'Result)
иначе First'Result = No_Element);
Если Length (Container) = 0, то First возвращает No_Element. В противном случае First возвращает курсор, обозначающий первый узел в Container.
функция Next (Position : Cursor) возвращает Cursor
с Nonblocking, Global => во всех, Use_Formal => null,
Post => (если Position = No_Element то Next'Result = No_Element);
с Nonblocking, Global => во всех, Use_Formal => null,
Post => (если Position = No_Element то Next'Result = No_Element);
Возвращает курсор, обозначающий преемника узла, обозначенного Position. Если Position обозначает последний узел, то возвращается No_Element. Если Position равно No_Element, то возвращается No_Element.
функция Next (Container : Map;
Position : Cursor) возвращает Cursor
с Nonblocking, Global => null, Use_Formal => null,
Pre => Position = No_Element или else
Has_Element (Container, Position)
иначе повысить Program_Error,
Post => (если Position = No_Element то Next'Result = No_Element
иначе если Next'Result = No_Element то
Position = Last (Container)
иначе Has_Element (Container, Next'Result));
Position : Cursor) возвращает Cursor
с Nonblocking, Global => null, Use_Formal => null,
Pre => Position = No_Element или else
Has_Element (Container, Position)
иначе повысить Program_Error,
Post => (если Position = No_Element то Next'Result = No_Element
иначе если Next'Result = No_Element то
Position = Last (Container)
иначе Has_Element (Container, Next'Result));
Возвращает курсор, обозначающий преемника узла, обозначенного Position в Container.
процедура Next (Position : вход-выход Cursor)
с Nonblocking, Global => во всех, Use_Formal => null;
с Nonblocking, Global => во всех, Use_Formal => null;
Эквивалентно Position := Next (Position).
процедура Next (Container : вход Map;
Position : вход-выход Cursor)
с Nonblocking, Global => null, Use_Formal => null,
Pre => Position = No_Element или else
Has_Element (Container, Position)
иначе повысить Program_Error,
Post => (если Position /= No_Element
то Has_Element (Container, Position));
Position : вход-выход Cursor)
с Nonblocking, Global => null, Use_Formal => null,
Pre => Position = No_Element или else
Has_Element (Container, Position)
иначе повысить Program_Error,
Post => (если Position /= No_Element
то Has_Element (Container, Position));
Эквивалентно Position := Next (Container, Position).
функция Find (Container : Map;
Key : Key_Type) возвращает Cursor
с Post => (если Find'Result = No_Element
то Has_Element (Container, Find'Result));
Key : Key_Type) возвращает Cursor
с Post => (если Find'Result = No_Element
то Has_Element (Container, Find'Result));
Если Length (Container) равно 0, то Find возвращает No_Element. В противном случае Find проверяет, присутствует ли в Container узел с ключом, эквивалентным Key. Если совпадение найдено, возвращается курсор, обозначающий соответствующий узел; в противном случае возвращается No_Element.
функция Element (Container : Map;
Key : Key_Type) возвращает Element_Type;
Key : Key_Type) возвращает Element_Type;
Эквивалентно Element (Find (Container, Key)).
функция Contains (Container : Map;
Key : Key_Type) возвращает Boolean;
Key : Key_Type) возвращает Boolean;
Эквивалентно Find (Container, Key) /= No_Element.
Абзацы 72 и 73 были перемещены выше.
процедура Iterate
(Container : вход Map;
Process : не null доступная процедура (Position : вход Cursor))
с Allows_Exit;
(Container : вход Map;
Process : не null доступная процедура (Position : вход Cursor))
с Allows_Exit;
Iterate вызывает Process.все с курсором, обозначающим каждый узел в Container, начиная с первого узла и перемещая курсор в соответствии с отношением преемника. Манипулирование курсорами Container запрещено во время выполнения вызова Process.все. Любое исключение, сгенерированное Process.все, передаётся.
Вложенный пакет Stable предоставляет тип Stable.Map, представляющий собой стабильную карту, которая не может расти и уменьшаться. Такую карту можно создать, вызвав функцию Copy или установив стабилизированный вид обычной карты.
Подпрограммы пакета map, имеющие параметр или результат типа Map, включены во вложенный пакет Stable с тем же спецификацией, за исключением следующих:
Tampering_With_Cursors_Prohibited, Tampering_With_Elements_Prohibited, Assign, Move, Insert, Include, Clear, Delete, Exclude, (для Ordered_Maps) Delete_First и Delete_Last, и (для Hashed_Maps) Reserve_Capacity
Операции этого пакета эквивалентны операциям обычных карт, за исключением того, что вызовы Tampering_With_Cursors_Prohibited и Tampering_With_Elements_Prohibited, которые встречаются в предусловиях, заменяются на False, а любые, встречающиеся в постусловиях, — на True.
Если стабильная карта объявлена с дискриминантом Base, обозначающим существующую обычную карту, стабильная карта представляет собой стабилизированный вид базовой обычной карты, и любая операция со стабильной картой отражается на базовой обычной карте. Пока существует стабилизированный вид, любая операция, манипулирующая элементами, выполняемая на базовой карте, запрещена. Закрытие стабильной карты, предоставляющей такой вид, снимает это ограничение на базовой обычной карте (хотя некоторые другие ограничения могут существовать из-за других одновременных итераций или стабилизированных видов).
Если стабильная карта объявлена без указания Base, объект обязательно инициализируется. Выражение инициализации стабильной карты, как правило, вызов Copy, определяет Length карты. Length стабильной карты никогда не изменяется после инициализации.
Ограниченные (временные) ошибки
Ограниченная ошибка для фактической функции, связанной с формальной подпрограммой-генератором, при вызове как части операции пакета map, заключается в изменении элементов любого параметра-карты операции. Либо повышается Program_Error, либо операция работает, как определено для значения карты до или после некоторых или всех модификаций карты.
Вызов любой подпрограммы, объявленной в видимой части пакета map, когда связанный контейнер завершен, является ограниченной ошибкой. Если операция принимает Container в качестве параметра вход-выход, она повышает Constraint_Error или Program_Error. В противном случае операция либо выполняется так, как это было бы для пустого контейнера, либо повышает Constraint_Error или Program_Error.
Ошибка выполнения
Значение Cursor является недействительным, если после его создания произошло любое из следующих событий:
- Карта, содержащая узел, который оно обозначает, завершена;
- Карта, содержащая узел, который оно обозначает, использовалась в качестве Цели вызова Assign или в качестве цели оператора присваивания;
- Карта, содержащая узел, который оно обозначает, использовалась в качестве Источника или Цели вызова Move; или
- Узел, который оно обозначает, был удален из карты, которая ранее содержала этот узел.
Результат «=» или Has_Element не определён, если эти функции вызываются с недействительным параметром курсора. Выполнение является ошибочным, если вызывается любая другая подпрограмма, объявленная в Containers.Hashed_Maps или Containers.Ordered_Maps, с недействительным параметром курсора.
Выполнение является ошибочным, если карта, связанная с результатом вызова Reference или Constant_Reference, завершена до завершения объекта результата, возвращенного вызовом Reference или Constant_Reference.
Требования к реализации
Никакие данные, связанные с объектом карты, не должны теряться при присваивании или выходе из области видимости.
Выполнение оператора присваивания для карты должно приводить к копированию элементов из исходной карты в целевую карту и изменению длины целевого объекта на длину исходного объекта.
Рекомендации по реализации
Move не должен копировать элементы и должен минимизировать копирование внутренних структур данных.
Если из операции с картой возникает исключение, не должно теряться памяти, и элементы не должны удаляться из карты, если это не указано в операции.