Index: src/natools-static_hash_maps.adb ================================================================== --- src/natools-static_hash_maps.adb +++ src/natools-static_hash_maps.adb @@ -198,10 +198,44 @@ procedure Write_Map_Body (Map : in Map_Description; Prefix : in String; File : in Ada.Text_IO.File_Type) is begin + if Map.Indefinite then + Ada.Text_IO.Put_Line + (File, + " function " & Prefix & "_Elements (Hash : " + & Prefix & "_Hash)"); + Ada.Text_IO.Put_Line + (File, + " return " & To_String (Map.Element_Type) & " is"); + Ada.Text_IO.Put_Line (File, " begin"); + Ada.Text_IO.Put_Line (File, " case Hash is"); + + declare + Pos : Natural := 0; + Cursor : Node_Lists.Cursor := Map.Nodes.First; + begin + while Node_Lists.Has_Element (Cursor) loop + Ada.Text_IO.Put_Line + (File, " when " & Image (Pos) & " =>"); + Ada.Text_IO.Put_Line + (File, + " return " + & To_String (Node_Lists.Element (Cursor).Name) + & ';'); + + Node_Lists.Next (Cursor); + Pos := Pos + 1; + end loop; + end; + + Ada.Text_IO.Put_Line (File, " end case;"); + Ada.Text_IO.Put_Line (File, " end " & Prefix & "_Elements;"); + Ada.Text_IO.New_Line (File); + end if; + Ada.Text_IO.Put_Line (File, " function " & To_String (Map.Function_Name) & " (Key : String) return " @@ -323,35 +357,49 @@ Pos := Pos + 1; Node_Lists.Next (Cursor); end loop; - Ada.Text_IO.Put_Line - (File, - " " & Prefix & "_Elements : constant array (0 .. " & Image (Last) - & ") of " & To_String (Map.Element_Type)); - Pos := 0; - Cursor := Map.Nodes.First; - while Node_Lists.Has_Element (Cursor) loop - if Pos = 0 then - Ada.Text_IO.Put (File, " := ("); - else - Ada.Text_IO.Put (File, " "); - end if; - - Ada.Text_IO.Put - (File, To_String (Node_Lists.Element (Cursor).Name)); - - if Pos = Last then - Ada.Text_IO.Put_Line (File, ");"); - else - Ada.Text_IO.Put_Line (File, ","); - end if; - - Pos := Pos + 1; - Node_Lists.Next (Cursor); - end loop; + if Map.Indefinite then + Ada.Text_IO.Put_Line + (File, + " subtype " & Prefix & "_Hash is Natural range 0 .. " + & Image (Last) & ';'); + Ada.Text_IO.Put_Line + (File, + " function " & Prefix & "_Elements (Hash : " + & Prefix & "_Hash)"); + Ada.Text_IO.Put_Line + (File, + " return " & To_String (Map.Element_Type) & ';'); + else + Ada.Text_IO.Put_Line + (File, + " " & Prefix & "_Elements : constant array (0 .. " & Image (Last) + & ") of " & To_String (Map.Element_Type)); + Pos := 0; + Cursor := Map.Nodes.First; + while Node_Lists.Has_Element (Cursor) loop + if Pos = 0 then + Ada.Text_IO.Put (File, " := ("); + else + Ada.Text_IO.Put (File, " "); + end if; + + Ada.Text_IO.Put + (File, To_String (Node_Lists.Element (Cursor).Name)); + + if Pos = Last then + Ada.Text_IO.Put_Line (File, ");"); + else + Ada.Text_IO.Put_Line (File, ","); + end if; + + Pos := Pos + 1; + Node_Lists.Next (Cursor); + end loop; + end if; end Write_Map_Private_Spec; procedure Write_Map_Public_Spec (Map : in Map_Description; @@ -570,11 +618,12 @@ begin Self := (Element_Type => Hold (""), Hash_Package_Name => Hold (""), Function_Name => Hold (""), Not_Found => Hold (""), - Nodes => Node_Lists.Empty_List); + Nodes => Node_Lists.Empty_List, + Indefinite => False); end Reset; procedure Insert (Self : in out Map_Description; @@ -582,10 +631,16 @@ Element_Name : in String) is begin Self.Nodes.Append (Node (Key, Element_Name)); end Insert; + + procedure Set_Definite (Self : in out Map_Description) is + begin + Self.Indefinite := False; + end Set_Definite; + procedure Set_Element_Type (Self : in out Map_Description; Name : in String) is begin @@ -606,10 +661,18 @@ Name : in String) is begin Self.Hash_Package_Name := Hold (Name); end Set_Hash_Package_Name; + + procedure Set_Indefinite + (Self : in out Map_Description; + Indefinite : in Boolean := True) is + begin + Self.Indefinite := Indefinite; + end Set_Indefinite; + procedure Set_Not_Found (Self : in out Map_Description; Name : in String) is begin @@ -620,19 +683,21 @@ function Map (Element_Type : String; Nodes : Node_Array; Hash_Package_Name : String := ""; Function_Name : String := "Element"; - Not_Found : String := "") + Not_Found : String := ""; + Indefinite : Boolean := False) return Map_Description is Result : Map_Description := (Element_Type => Hold (Element_Type), Hash_Package_Name => Hold (Hash_Package_Name), Function_Name => Hold (Function_Name), Not_Found => Hold (Not_Found), - Nodes => Node_Lists.Empty_List); + Nodes => Node_Lists.Empty_List, + Indefinite => Indefinite); begin for I in Nodes'Range loop Result.Nodes.Append (Nodes (I)); end loop; Index: src/natools-static_hash_maps.ads ================================================================== --- src/natools-static_hash_maps.ads +++ src/natools-static_hash_maps.ads @@ -44,10 +44,13 @@ (Self : in out Map_Description; Key : in String; Element_Name : in String); -- Add the pair Key and element designated by Name. + procedure Set_Definite (Self : in out Map_Description); + -- Use an array to store definite elements (default) + procedure Set_Element_Type (Self : in out Map_Description; Name : in String); -- String used to desginate the returning type of the element function. -- This must be set. @@ -60,10 +63,17 @@ procedure Set_Hash_Package_Name (Self : in out Map_Description; Name : in String); -- Set the package name where the perfect hash function will be write. -- Defaults to "._Hash". + + procedure Set_Indefinite + (Self : in out Map_Description; + Indefinite : in Boolean := True); + -- Set whether element type is indefinite (and returned by a function + -- containing a case statement) or definite (and stored in a global + -- array). procedure Set_Not_Found (Self : in out Map_Description; Name : in String); -- If non-empty, when element function is called with an unknown key, @@ -72,11 +82,12 @@ function Map (Element_Type : String; Nodes : Node_Array; Hash_Package_Name : String := ""; Function_Name : String := "Element"; - Not_Found : String := "") + Not_Found : String := ""; + Indefinite : Boolean := False) return Map_Description; -- Create a map in a single call type Map_Package is private; @@ -151,10 +162,11 @@ Element_Type : String_Holder; Hash_Package_Name : String_Holder; Function_Name : String_Holder; Not_Found : String_Holder; Nodes : Node_Lists.List; + Indefinite : Boolean := False; end record; package Map_Lists is new Ada.Containers.Doubly_Linked_Lists (Map_Description);