Здесь я говорю об Аде 2012.
Я позволю коду говорить первым:
with Ada.Containers.Hashed_Maps;
with Ada.Strings.Unbounded;
with Ada.Strings.Unbounded.Hash_Case_Insensitive;
with Ada.Strings.Unbounded.Equal_Case_Insensitive;
package Environments is
type Environment is tagged private;
function Variable (
E : in Environment;
Name : in Ada.Strings.Unbounded.Unbounded_String
)
return Ada.Strings.Unbounded.Unbounded_String
with Inline;
procedure Set_Variable (
E : in out Environment;
Name : in Ada.Strings.Unbounded.Unbounded_String;
Value : in Ada.Strings.Unbounded.Unbounded_String
)
with Inline;
private
package Variable_Maps is new Ada.Containers.Hashed_Maps (
Key_Type => Ada.Strings.Unbounded.Unbounded_String,
Element_Type => Ada.Strings.Unbounded.Unbounded_String,
Hash => Ada.Strings.Unbounded.Hash_Case_Insensitive,
Equivalent_Keys => Ada.Strings.Unbounded.Equal_Case_Insensitive,
"=" => Ada.Strings.Unbounded."="
);
type Environment is tagged record
Variables : Variable_Maps.Map;
end record;
end Environments;
Здесь у нас есть пример пакета, довольно хорошо иллюстрирующий мою проблему. Я храню некоторые переменные среды в Hashed_Map
, но я хочу создать уровень абстракции поверх стандартного контейнера, чтобы в будущем я мог изменить лежащий в основе контейнер без изменения какого-либо кода в моих клиентах пакета.
Получить и установить переменные легко - как было заявлено выше. Настоящая проблема заключается в повторении. Я хотел бы, чтобы клиенты моего пакета перебирали среду и легко получали как ключ, так и значение для каждого элемента.
Поскольку я использую Ada 2012, лучше всего использовать итераторы, но как? Я мог бы вернуть курсор нижележащему контейнеру, но, опять же, интерфейс этого курсора будет зависеть от контейнера.
Как лучше всего добиться такой абстракции по сравнению со стандартной итерацией контейнера?