with Integer_Hashed_Sets;  use Integer_Hashed_Sets;
--with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;

procedure Test_Hashed_Sets is

   subtype Integer_Subtype is Integer range 1 .. 1000;

   package Random_Numbers is
      new Ada.Numerics.Discrete_Random (Integer_Subtype);

   use Random_Numbers;

   G : Generator;

   S, S2 : Container_Type;

   E : Integer;
   I, J : Iterator_Type;
   B : Boolean;

   N : Natural;

begin

   Reset (G);

   pragma Assert (Length (S) = 0);
   pragma Assert (S = S2);

   S2 := S;
   pragma Assert (S = S2);

   Assign (Target => S2, Source => S);
   pragma Assert (S = S2);

   Insert (S, 42, I, B);
   pragma Assert (Length (S) = 1);
   pragma Assert (B);
   pragma Assert (Element (I) = 42);
   pragma Assert (I = First (S));
   pragma Assert (Succ (S, I) = Back (S));

   S2 := S;
   pragma Assert (S = S2);

   Assign (Target => S2, Source => S);
   pragma Assert (S = S2);

   J := Find (S, 42);
   pragma Assert (J /= Back (S));
   pragma Assert (Element (J) = 42);

   S2 := S;
   pragma Assert (S = S2);

   Assign (Target => S2, Source => S);
   pragma Assert (S = S2);

   Put_Line ("inserting");

   loop

      N := Length (S);

      exit when N > 900;

      E := Random (G);

      Insert (S, E, I, B);

      pragma Assert (Element (I) = E);

      J := Find (S, E);
      pragma Assert (J /= Back (S));
      pragma Assert (Element (J) = E);

      if B then
         pragma Assert (Length (S) = N + 1);
         null;
      else
         pragma Assert (Length (S) = N);
         null;
      end if;

      S2 := S;
      pragma Assert (S = S2);

      Assign (Target => S2, Source => S);
      pragma Assert (S = S2);

   end loop;

   Put_Line ("deleting");

   while not Is_Empty (S) loop

      I := First (S);

      for J in 1 .. Random (G) mod Length (S) loop
         Increment (S, I);
      end loop;

      pragma Assert (I /= Back (S));

      E := Element (I);

      Delete (S, I);
      pragma Assert (not Is_In (E, S));

      S2 := S;
      pragma Assert (S = S2);

      Assign (Target => S2, Source => S);
      pragma Assert (S = S2);

   end loop;

end Test_Hashed_Sets;

