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;
next 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