Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing map to common procedure

Tags:

ada

The Java programming languages frequently uses interfaces like java.util.Map.

In the following example two custom map packages are created by using the generic packages Ada.Containers.Hashed_Maps and Ada.Containers.Ordered_Maps. Both generic packages are offering the functions/procedures Clear and Length. The procedures Do_Something are using this functions/procedures to clear the passed map and to print the container length (stupid example ...).

I am right then it is not possible to create a procedure Do_Something_Special that would accept maps of both types Map_One.Map and Map_Two.Map? In Java it would be possible to define a parameter with the type Map<Natural, Unbounded_String>.

with Ada.Containers.Hashed_Maps;
with Ada.Containers.Ordered_Maps;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO;

procedure Main is
   function Hash (Value : Natural) return Ada.Containers.Hash_Type is
   begin
      return Ada.Containers.Hash_Type (Value);
   end Hash;

   package Map_One is new Ada.Containers.Hashed_Maps
     (Key_Type        => Natural,
      Element_Type    => Unbounded_String,
      Hash            => Hash,
      Equivalent_Keys => "=");

   package Map_Two is new Ada.Containers.Ordered_Maps
     (Key_Type     => Natural,
      Element_Type => Unbounded_String);

   procedure Do_Something (Input : in out Map_One.Map) is
   begin
      Input.Clear;

      Ada.Text_IO.Put_Line ("Length: " & Input.Length'Image);
   end Do_Something;

   procedure Do_Something (Input : in out Map_Two.Map) is
   begin
      Input.Clear;

      Ada.Text_IO.Put_Line ("Length: " & Input.Length'Image);
   end Do_Something;

   procedure Do_Something_Special (Input : in out ???) is
   begin
      Input.Clear;

      Ada.Text_IO.Put_Line ("Length: " & Input.Length'Image);
   end Do_Something_Special;
begin
   null;
end Main;
like image 764
Marcello90 Avatar asked Jan 16 '20 21:01

Marcello90


People also ask

What is a process map?

What is a Process Map? A process map visually shows the steps of a work activity and the people who are involved in carrying out each step. When mapping a process you simply draw a box for each step and connect them with arrows to show a flow. You can use an online tool to easily create a Process Map.

What are some common process mapping mistakes operations make?

Now that you know why they are so valuable to your organization, you’re ready to delve into the common process mapping mistakes operations people tend to make when creating them. 1. Making Process Maps Too Complex It’s nice to know that a process map isn’t linear like a checklist is.

Are your process maps confusing your employees?

This will certainly create confusion, especially if the same employees are utilizing various process maps that all look different. The text, the shapes (i.e. boxes, ovals, diamonds, etc.), the specific language used in each document – if these things are not consistent, they can end up confusing your workers and can even result in costly mistakes.

Are you going too fast with your process maps?

But whether it’s because of the dread of having to create the process maps, or because of the initial excitement of creating systems for your business, going too fast can be a problem. Inevitably, you end up missing steps or fail to provide sufficient information to the end user.


1 Answers

Just like in Java you can use generics or interfaces.

A generic only solution:

generic
    type Map is private;
    with procedure Clear(Self : in out Map);
    with function Length(Self : Map) return Ada.Containers.Count_Type;
procedure Do_Something_Special(Input : in out Map);
procedure Do_Something_Special(Input : in out Map) is
begin
    Clear(Input);
    Ada.Text_IO.Put_Line("Length: " & Length(Input)'Image);
end Do_Something_Special;

procedure Do_Something_Map_One is new Do_Something_Special
    (Map    => Map_One.Map,
     Clear  => Map_One.Clear,
     Length => Map_One.Length);

procedure Do_Something_Map_Two is new Do_Something_Special
    (Map    => Map_Two.Map,
     Clear  => Map_Two.Clear,
     Length => Map_Two.Length);

If instead you want to go the route of using a Map interface you can do the following:

Create a generic interface for any key/value types

use Ada.Containers;

generic
    type Key_Type is private;
    type Element_Type is private;
package Map_Interfaces is

    type Map_Interface is interface;
    procedure Clear(Self : in out Map_Interface) is abstract;
    function Length(Self : Map_Interface) return Count_Type is abstract;

    -- other operations

end Map_Interfaces;

Next implement it for the key/value types you want:

package My_Map_Interfaces is new Map_Interfaces
    (Key_Type     => Natural,
     Element_Type => Unbounded_String);

use My_Map_Interfaces;

Now you are able to use the class type of the interface to operate on any map that implements that interface:

procedure Do_Something_Special_1(Input : in out Map_Interface'Class) is
begin
    Input.Clear;
    Ada.Text_IO.Put_Line ("Length: " & Input.Length'Image);
end Do_Something_Special_1;

Then you just need to extend the Ada map types and implement the interface:

type Map_1 is new Map_One.Map and Map_Interface with null record;
type Map_2 is new Map_Two.Map and Map_Interface with null record;

M1 : Map_1;
M2 : Map_2;

and you can call it this way:

Do_Something_Special_1(M1);
Do_Something_Special_1(M2);

OR you an create another generic function if you want static dispatch instead of dynamic:

generic
    type Map is new Map_Interface with private;
procedure Do_Something_Special_2(Input : in out Map);

procedure Do_Something_Special_2(Input : in out Map) is
begin
    Input.Clear;
    Ada.Text_IO.Put_Line ("Length: " & Input.Length'Image);
end Do_Something_Special_2;

procedure Do_Something_Map_1 is new Do_Something_Special_2(Map_1);
procedure Do_Something_Map_2 is new Do_Something_Special_2(Map_2);

and call it like this:

Do_Something_Map_1(M1);
Do_Something_Map_2(M2);
like image 112
Jere Avatar answered Oct 25 '22 07:10

Jere