comp.lang.ada
 help / color / mirror / Atom feed
From: matthew_heaney@acm.org (Matthew Heaney)
Subject: Active Iteration (was: How to use abstract data types)
Date: 1998/05/05
Date: 1998-05-05T00:00:00+00:00	[thread overview]
Message-ID: <matthew_heaney-ya023680000505982057280001@news.ni.net> (raw)


Here's the idea I had for the library iterator.  The Library_Package.Test
package exports an active iterator that I was hoping to use to iterate over
a Test_Library.  

However, I can't get this code to compile!  My compiler is telling me the
generic actual types don't match the formal discriminant types.

If your compiler can compile this, let me know and I'll report a bug to
ACT.  If this is simply an illegal Ada program, then maybe someone can
figure out an alternative solution.

The idea was to make the List_Books operation a generic procedure that
imports an iterator type as a generic formal type, to iterate over the
library object passed in.  I do it this way because importing an iterator
as derived from an abstract root iterator type won't work, because formal
derived types cannot have a known discriminant (see RM95 12.5.1 (11), a
bummer of a paragraph).  So I just import everything as a non-tagged type
(even though the actual type may in fact be tagged), and import the ops
formal subprogram parameters ("implementation inheritance").

But I can't get the instantiation of List_Books to compile.  Maybe you'll
have more luck.

Matt



package Library_Package is

    type Library is abstract tagged null record;
    type Book is abstract tagged null record;

    function Title (Bk : Book) return string is abstract;

end Library_Package;


package Library_Package.Test is

    type Test_Library is new Library with private;

    type Test_Book is new Book with private;

    type Test_Library_Acc is access all Test_Library;

    type Test_Iterator (Lib : access Test_Library'Class) is
        limited private;

    function Title (Bk : Test_Book) return string;
    procedure Scan_For_Substring (Iter   : in out Test_Iterator;
                                  Substr : in string);
    function Is_Done (Iter : Test_Iterator) return boolean;
    function Get_Book (Iter : Test_Iterator) return Book'Class;
    procedure Advance (Iter : in out Test_Iterator);

private
    type String_P is access string;
    type Book_Info is record
       Title : String_P;
    end record;

    type Test_Book is new Book with record
        Info : Book_Info;
    end record;

    type Book_Array is array (Natural range <>) of Test_Book;

    type Test_Library is
      new Library with record
         Books : Book_Array (1..6) :=
        ( (Info => (Title => new string' ("A Time To Kill"))),
          (Info => (Title => new string' ("The Firm"))),
          (Info => (Title => new string' ("The Pelican Brief"))),
          (Info => (Title => new string' ("The Client"))),
          (Info => (Title => new string' ("The Rainmaker"))),
          (Info => (Title => new string' ("The Runaway Jury"))) );
      end record;


    type Test_Iterator (Lib : access Test_Library'Class) is
       limited record
         Search_String : String_P;
         Index         : Natural;
       end record;

end Library_Package.Test;


with Ada.Strings.Fixed;
package body Library_Package.Test is

    function Title (Bk : Test_Book) return string is
    begin
        return Bk.Info.Title.all;
    end Title;

    procedure Search (Iter : in out Test_Iterator) is
       use Ada.Strings.Fixed;
       Books : Book_Array renames Iter.Lib.Books;
    begin
       while Iter.Index <= Iter.Lib.Books'last loop
          declare
             Book : Test_Book renames Books (Iter.Index);

             Title : String renames Book.Info.Title.all;

             Search_String : String renames Iter.Search_String.all;
          begin
             exit when Index (Title, Search_String) /= 0;
          end;

          Iter.Index := Iter.Index + 1;

        end loop;
    end Search;

    procedure Scan_For_Substring (Iter   : in out Test_Iterator;
                                  Substr : in string) is
    begin
        Iter.Search_String := new string' (Substr);
        Iter.Index := Iter.Lib.Books'first;
        Search (Iter);
    end Scan_For_Substring;

    function Is_Done (Iter : Test_Iterator) return boolean is
    begin
        return (Iter.Index > Iter.Lib.Books'last);
    end Is_Done;

    function Get_Book (Iter : Test_Iterator) return Book'Class is
    begin
        return Iter.Lib.Books (Iter.Index);
    end Get_Book;

    procedure Advance (Iter : in out Test_Iterator) is
    begin
        Iter.Index := Iter.Index + 1;
        Search (Iter);
    end Advance;

end Library_Package.Test;


package Library_Package.List is

   generic
      type Source_Library (<>) is limited private;

      type Source_Iterator
        (Lib : access Source_Library) is limited private;

      with function Is_Done
        (Iter : Source_Iterator) return Boolean is <>;

      with procedure Advance
        (Iter : in out Source_Iterator) is <>;

      with function Get_Book
        (Iter : Source_Iterator) return Book'Class is <>;

      with procedure Scan_For_Substring 
        (Iter  : in out Source_Iterator;
         Subst : in     String) is <>;
   procedure List_Books 
      (Lib : access Source_Library; Substr : in string);

end Library_Package.List;


with Text_IO;
package body Library_Package.List is

   procedure List_Books 
     (Lib    : access Source_Library; 
      Substr : in string) is

      Iter : Source_Iterator (Lib);
    begin
        Scan_For_Substring (Iter, Substr);

        while not Is_Done (Iter) loop

            declare
                Bk : Book'class := Get_Book (Iter);
            begin
                Text_IO.Put_Line (Title (Bk));
            end;

            Advance (Iter);

        end loop;
    end List_Books;

end Library_Package.List;



with Library_Package.List;

procedure Library_Package.Test.List_Books is
  new Library_Package.List.List_Books
  (Source_Library  => Test_Library'Class,
   Source_Iterator => Test_Iterator);
   

with Library_Package.Test.List_Books;
use Library_Package.Test.List_Books;

procedure Libtest2 is
    The_Lib : Library_Package.Test.Test_Library;
begin
    List_Books (The_Lib, "m");
end Libtest2;




             reply	other threads:[~1998-05-05  0:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-05-05  0:00 Matthew Heaney [this message]
  -- strict thread matches above, loose matches on Subject: below --
1998-05-08  0:00 Active Iteration (was: How to use abstract data types) adam
1998-05-09  0:00 ` Matthew Heaney
1998-05-09  0:00   ` Simon Wright
1998-05-13  0:00 adam
1998-05-13  0:00 ` Matthew Heaney
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox