All pastes #928500 Raw Edit

kantis

public text v1 · immutable
·published 2008-03-05 02:45 UTC
rendered paste body
===================================
============ .ads =================
===================================

generic
   type Data_Type is private;
   type Key_Type is private;
   with function Get_Key(Object : in Data_Type) return Key_Type;
   with procedure Put(Object : in Data_Type);
   with function ">"(Left : in Data_Type; Right : in Data_Type) return Boolean;
   with function "="(Left : in Data_Type; Right : in Data_Type) return Boolean;

package Generic_Sorted_List is
   type Element_Type is private;
   type List_Type is private;

   function Empty(List : in List_Type) return Boolean;

   function Member(Object  : in Data_Type;
                   List : in List_Type) return Boolean;
   procedure Insert(Object : in Data_Type; List : in out List_Type);
   procedure Put(List : in List_Type);
   procedure Remove(Key : in Key_Type; List : in out List_Type);
   procedure Delete(List : out List_Type);
   function Find(Object : in Key_Type;
                 List : in List_Type) return Data_Type;
   procedure Find(New_List : out Data_Type;
                  Object : in Key_Type;
                  List : in List_Type);
   function Length(List : in List_Type) return Integer;

   Element_Not_Found : exception;

private
   type List_Type is
     access Element_Type;

   type Element_Type is
      record
         Data : Data_Type;
         Next : List_Type;
      end record;
end Generic_Sorted_List;


===================================
============ .adb =================
===================================


with Ada.Unchecked_Deallocation;

package body Generic_Sorted_List is

   procedure Free is
      new Ada.Unchecked_Deallocation(Object => Element_Type,
                                     Name => List_Type);

   function Empty(List : in List_Type) return Boolean is
   begin
      if List = null then
         return True;
      else
         return False;
      end if;
   end Empty;

   function Member(Object : in Data_Type;
                   List : in List_Type) return Boolean is
      Iterator : List_Type;
   begin
      Iterator := List;
      while not Empty(Iterator) loop
         if Object = Iterator.Data then
            return True;
         end if;
         Iterator := Iterator.Next;
      end loop;
      return False;
   end Member;

   procedure Insert(Object : in Data_Type;
                    List : in out List_Type) is
      Iterator,Prev_Element : List_Type;
      Changed : Boolean := False;
      E : List_Type;
   begin
      Iterator := List;
      Prev_Element := null;

      while not Empty(Iterator) and not Changed loop
         if Iterator.Data > Object then
            E := new Element_Type'(Data => Object, Next => Iterator);
            if Prev_Element /= null then
               Prev_Element.Next := E;
            else
               List := E;
            end if;
            Changed := True;
         elsif Iterator.Data = Object then
            Changed := True;

         else
            Prev_Element := Iterator;
            Iterator := Iterator.Next;
         end if;
      end loop;

      if not Changed then
         E := new Element_Type'(Data => Object, Next => null);
         if Empty(List) then
            List := E;
         else
            Prev_Element.Next := E;
         end if;
      end if;
   end Insert;

   procedure Put(List : in List_Type) is
      Iterator : List_Type;
   begin
      Iterator := List;
      for I in 1..Length(List) loop
         Put(Iterator.Data);
         Iterator := Iterator.Next;
      end loop;
   end Put;

   procedure Remove(Key : in Key_Type; List : in out List_Type) is
      Current_Element : List_Type;
      Prev_Element : List_Type;
   begin

      if not Empty(List) then
         Current_Element := List;
         Prev_Element := null;

         While not Empty(Current_Element) loop
            if Get_Key(Current_Element.Data) = Key then
               if Prev_Element /= null then
                  Prev_Element.Next := Current_Element.Next;
               end if;
               Free(Current_Element);
               Current_Element := null;
            else
                 Prev_Element := Current_Element;
                 Current_Element := Current_Element.Next;
            end if;

         end loop;

         if not Empty(Current_Element) then
            raise Element_Not_Found;
         end if;

      end if;
   end Remove;

   procedure Delete(List : out List_Type) is
      Current_Element : List_Type;
      Next_Element : List_Type;
   begin
      if not Empty(List) then
         Current_Element := List.Next;
         Free(List);
         for I in 1..Length(Current_Element) loop
            Next_Element := Current_Element.Next;
            Free(Current_Element);
            Current_Element := Next_Element;
         end loop;
      end if;
   end Delete;

   function Find(Object : in Key_Type; List : in List_Type) return Data_Type is
      Iterator : List_Type;
   begin
      Iterator := List;
      while not Empty(Iterator) loop
         if Object = Get_Key(Iterator.Data) then
            return Iterator.Data;
         end if;
         Iterator := Iterator.Next;
      end loop;
      raise Element_Not_Found;
   end Find;

   procedure Find(New_List : out Data_Type; Object : in Key_Type; List : in List_Type) is
   begin
      New_List := Find(Object,List);
   end Find;

   function Length(List : in List_Type) return Integer is
      Iterator : List_Type;
      Resultat : Integer := 0;
   begin
      Iterator := List;

      while not Empty(Iterator) loop
         Resultat := Resultat + 1;
         Iterator := Iterator.Next;
      end loop;
      return Resultat;
   end Length;
end Generic_Sorted_List;