From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,2cddfaac8a770e6b,start X-Google-Attributes: gid103376,public From: matthew_heaney@acm.org (Matthew Heaney) Subject: Active Iteration (was: How to use abstract data types) Date: 1998/05/05 Message-ID: X-Deja-AN: 350654260 Content-Transfer-Encoding: 8bit Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Organization: Network Intensive Newsgroups: comp.lang.ada Date: 1998-05-05T00:00:00+00:00 List-Id: 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;