-- $Date: 2004/02/14 09:51:42 $
-- $Revision: 1.11 $
-- $Author: jcrocholl $

with Ada.Unchecked_Deallocation;

package body String_Lists is

   ---------------
   -- Adding items
   ---------------

   -- Insert an item at the end of the list.
   function Push
     (This : access String_List-- Push into this list.
     return Item_Access          -- The newly created item.
     renames Inner_Lists.Push;

   -- Insert an item at the end of the list.
   procedure Push
     (This    : access String_List-- Insert into this list.
      Content : in String) is       -- The new item.
   begin
      To_String_Access(Content, Push(This).Content);
   end Push;

   -- Insert an item at the beginning of the list.
   function Unshift
     (This : access String_List-- Unshift into this list.
     return Item_Access          -- The newly created item.
     renames Inner_Lists.Unshift;

   -- Insert an item at the beginning of the list.
   procedure Unshift
     (This    : access String_List-- Insert into this list.
      Content : in String) is       -- The new item.
   begin
      To_String_Access(Content, Unshift(This).Content);
   end Unshift;

   -----------------
   -- Removing items
   -----------------

   procedure Free is new Ada.Unchecked_Deallocation(Item, Item_Access);

   -- Remove an item at the end of the list.
   function Pop
     (This : access String_List-- Pop out of this list.
     return Item_Access          -- The removed item.
     renames Inner_Lists.Pop;

   -- Remove an item at the end of the list.
   function Pop
     (This : access String_List-- Remove from this list.
     return String               -- The new item.
   is
      Item   : Item_Access := Pop(This);
      Result : String := To_String(Item.Content);
   begin
      Free(Item.Content);
      Free(Item);
      return Result;
   end Pop;

   -- Remove an item at the beginning of the list.
   function Shift
     (This : access String_List-- Shift out of this list.
     return Item_Access          -- The removed item.
     renames Inner_Lists.Shift;

   -- Remove an item at the beginning of the list.
   function Shift
     (This : access String_List-- Remove from this list.
     return String               -- The new item.
   is
      Item   : Item_Access := Shift(This);
      Result : String := To_String(Item.Content);
   begin
      Free(Item.Content);
      Free(Item);
      return Result;
   end Shift;

   --------------------------------------
   -- Manipulating a list while iterating
   --------------------------------------

   -- Insert an item directly before the item at the current iteration
   -- pointer.
   function Insert_Before_Current
     (This : access String_List-- The list to modify.
     return Item_Access          -- The newly created item.
     renames Inner_Lists.Insert_Before_Current;

   -- Insert an item directly after the item at the current iteration
   -- pointer.
   function Insert_After_Current
     (This : access String_List-- The list to modify.
     return Item_Access          -- The newly created item.
     renames Inner_Lists.Insert_After_Current;

   --------------------
   -- First and last item
   --------------------

   -- Read the first item in the list.
   function First
     (This : access String_List-- Read from this list.
     return String is            -- The first item.
   begin
      return To_String(Inner_Lists.First(This));
   end First;

   -- Read the last item in the list.
   function Last
     (This : access String_List-- Read from this list.
     return String is            -- The last item.
   begin
      return To_String(Inner_Lists.Last(This));
   end Last;

   ------------------------
   -- Iterating over a list
   ------------------------

   -- Get the content of the next item.
   function Next_Content
     (This : access String_List-- The list to iterate over.
     return String is            -- The content of the next item.
   begin
      return To_String(Inner_Lists.Next_Content(This));
   end Next_Content;

   -- Read the item at the current iteration pointer.
   function Current
     (This : access String_List-- The list to iterate over.
     return String is            -- Current item.
   begin
      return To_String(Inner_Lists.Current(This));
   end Current;

   -----------------------------------
   -- Manipulate list while iterating.
   -----------------------------------

   -- Update the item at the current iteration pointer.
   procedure Update_Current
     (This    : access String_List-- The list to modify.
      Content : in String) is       -- New content for the current item.
   begin
      To_String_Access(Content, Current_Item(This).Content);
   end Update_Current;

   -- Insert an item directly before the item at the current iteration
   -- pointer.
   procedure Insert_Before_Current
     (This    : access String_List-- The list to modify.
      Content : in String) is       -- The item to insert.
   begin
      To_String_Access(Content, Insert_Before_Current(This).Content);
   end Insert_Before_Current;

   -- Insert an item directly after the item at the current iteration
   -- pointer.
   procedure Insert_After_Current
     (This    : access String_List-- The list to modify.
      Content : in String) is       -- The item to insert.
   begin
      To_String_Access(Content, Insert_After_Current(This).Content);
   end Insert_After_Current;

   ------------------------
   -- Item direct iteration
   ------------------------

   -- Read an item's content.
   function Item_Content
     (This : access Item-- Read content from this item.
     return String is     -- Content of this item.
   begin
      return To_String(Inner_Lists.Item_Content(This));
   end Item_Content;

   -- Change an item's content.
   procedure Update_Item
     (This    : access Item;  -- Modify this item.
      Content : in String) is -- New content.
   begin
      To_String_Access(Content, This.Content);
   end Update_Item;

end String_Lists;