Created
February 23, 2021 20:51
-
-
Save flyx/70abba5548474ceabc838f288e34daa9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
with Ada.Text_IO; use Ada.Text_IO; | |
with Ada.Containers.Hashed_Maps; use Ada.Containers; | |
with Ada.Iterator_Interfaces; | |
procedure Main is | |
package Tiles is | |
-- Implementation is completely hidden | |
type Tile_Type is private; | |
type Cursor is private; | |
type Tile_Set is tagged private | |
with Default_Iterator => Iterate, | |
Iterator_Element => Tile_Type, | |
Constant_Indexing => Constant_Reference; | |
function Has_Element (Position: Cursor) return Boolean; | |
package Tile_Set_Iterator_Interfaces is new | |
Ada.Iterator_Interfaces (Cursor, Has_Element); | |
type Constant_Reference_Type | |
(Element : not null access constant Tile_Type) is null record | |
with Implicit_Dereference => Element; | |
function Iterate (Container: in Tile_Set) return | |
Tile_Set_Iterator_Interfaces.Forward_Iterator'Class; | |
function Constant_Reference (Container : aliased in Tile_Set; | |
Position : Cursor) | |
return Constant_Reference_Type; | |
type Tile_Key is private; | |
procedure Add (Collection : in out Tile_Set; Tile : Tile_Type); | |
function Get (Collection : in Tile_Set; Key : Natural) return Tile_Type; | |
function Make (Key : Natural; Data : Integer) return Tile_Type; | |
function Image (Tile : Tile_Type) return String; | |
private | |
type Tile_Key is record | |
X : Natural; | |
end record; | |
function Tile_Hash (K : Tile_Key) return Hash_Type is | |
(Hash_Type (K.X)); | |
type Tile_Type is record | |
Key : Tile_Key; | |
Data : Integer; | |
end record; | |
package Tile_Matrix is new Ada.Containers.Hashed_Maps | |
(Element_Type => Tile_Type, | |
Key_Type => Tile_Key, | |
Hash => Tile_Hash, | |
Equivalent_Keys => "="); | |
use Tile_Matrix; | |
type Tile_Set is tagged record | |
Data : aliased Tile_Matrix.Map; | |
end record; | |
type Cursor is record | |
Data : Tile_Matrix.Cursor; | |
end record; | |
end Tiles; | |
package body Tiles is | |
type Iterator_Type (Data : access constant Tile_Matrix.Map) is new Tile_Set_Iterator_Interfaces.Forward_Iterator with null record; | |
function First (Object : Iterator_Type) return Cursor is | |
(Cursor'(Data => Object.Data.Iterate.First)); | |
function Next (Object : Iterator_Type; Position : Cursor) return Cursor is | |
(Cursor'(Data => Object.Data.Iterate.Next (Position.Data))); | |
function Has_Element (Position: Cursor) return Boolean is | |
(Tile_Matrix.Has_Element (Position.Data)); | |
function Iterate (Container: in Tile_Set) return | |
Tile_Set_Iterator_Interfaces.Forward_Iterator'Class is | |
(Iterator_Type'(Data => Container.Data'Access)); | |
function Constant_Reference (Container : aliased in Tile_Set; | |
Position : Cursor) | |
return Constant_Reference_Type is | |
(Constant_Reference_Type'(Element => Container.Data.Constant_Reference (Position.Data).Element)); | |
procedure Add (Collection : in out Tile_Set; Tile : Tile_Type) is | |
begin | |
Collection.Data.Include (Key => Tile.Key, New_Item => Tile); | |
end Add; | |
function Get (Collection : in Tile_Set; Key : Natural) return Tile_Type is | |
K : Tile_Key := (X => Key); | |
C : Tile_Matrix.Cursor := Collection.Data.Find (Key => K); | |
begin -- For illustration, would need to handle missing keys | |
return Result : Tile_Type do | |
Result := Collection.Data (C); | |
end return; | |
end Get; | |
function Image (Tile : Tile_Type) return String is | |
(Tile.Key.X'Image & '=' & Tile.Data'Image); | |
function Make (Key : Natural; Data : Integer) return Tile_Type is | |
New_Key : Tile_Key := (X => Key); | |
begin | |
return Result : Tile_Type do | |
Result.Key := New_Key; | |
Result.Data := Data; | |
end return; | |
end Make; | |
end Tiles; | |
use Tiles; | |
S : Tile_Set; | |
T : Tile_Type; | |
begin | |
S.Add (Make (Key => 1, Data => 10)); | |
T := S.Get (1); | |
Put_Line (Image (T)); -- 1, 10 | |
S.Add (Make (Key => 2, Data => 20)); | |
T := S.Get (2); | |
Put_Line (Image (T)); -- 1, 20 | |
for X of S loop | |
Put_Line (Image (X)); | |
end loop; | |
end Main; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment