with Integer_Character_Maps;  use Integer_Character_Maps;
with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Integer_Text_IO;  use Ada.Integer_Text_IO;
with Ada.Containers;  use Ada.Containers;

procedure Test_Maps is

   procedure Print (M : in Map);

   procedure Print (M : in Map) is
      I : Cursor := First (M);
   begin
      Put (Count_Type'Image (Length (M)));
      Put ('/');
      Put (Count_Type'Image (Capacity (M)));
      Put (": ");

      while I /= No_Element loop
         Put (Key (I), Width => 0);
         Put (' ');
         Next (I);
      end loop;

      New_Line;
   end Print;


   subtype Key_Subtype is Integer; --  range 0 .. 75;

   package Random_Keys is
      new Ada.Numerics.Discrete_Random (Key_Subtype);

   subtype Element_Subtype is Character range ' ' .. '~';

   package Random_Elements is
      new Ada.Numerics.Discrete_Random (Element_Subtype);

   GK : Random_Keys.Generator;
   GE : Random_Elements.Generator;

   use Random_Keys, Random_Elements;

   M, M2 : Map;

   K : Integer;
   E : Character;

   C, C2 : Cursor;
   B : Boolean;

   N : Integer;

begin

   Reset (GK);
   Reset (GE);

   Print (M);

   M2 := M;
   pragma Assert (M2 = M);

   for I in 1 .. 100 loop

      K := Random (GK) mod 75;
      E := Random (GE);

      C := Find (M, K);

      Insert (M, K, E, C2, B);
      pragma Assert (Key (C2) = K);

      if B then
         pragma Assert (C = No_Element);
         pragma Assert (Element (C2) = E);
         null;
      else
         pragma Assert (C = C2);
         null;
      end if;

      pragma Assert (Contains (M, K));

      M2 := M;
      pragma Assert (M2 = M);

      Print (M);

   end loop;

   New_Line;

   while not Is_Empty (M) loop

      C := First (M);

      N := Random (GK) mod Count_Type'Pos (Length (M));

      for I in 1 .. N loop
         Next (C);
      end loop;

      pragma Assert (C /= No_Element);

      K := Key (C);

      Delete (M, C);
      pragma Assert (not Contains (M, K));

      Exclude (M, K);  -- should have no effect

      M2 := M;
      pragma Assert (M2 = M);

      Print (M);

   end loop;


end Test_Maps;


