From: Richard Irvine <Richard.Irvine@eurocontrol.fr>
Subject: Re: Translate this into Ada ...
Date: 1996/08/22
Date: 1996-08-22T00:00:00+00:00 [thread overview]
Message-ID: <321C5BB1.3B2F@eurocontrol.fr> (raw)
In-Reply-To: 4vfb15$ujr@watnews1.watson.ibm.com
Many thanks to Norman Cohen for his comprehensive
reply. I certainly learnt something about Ada 95,
namely that the body of the function
> function New_Iterator_For
> (Collection: Integer_List_Type)
> return Abstract_Integer_Collections.Iterator_Type'Class;
>
can return a member of the class rather than something which
is of type Iterator_Type'Class, i.e.
> type Integer_List_Iterator_Type is
> new Abstract_Integer_Collections.Iterator_Type with private;
> function New_Iterator_For
> (Collection: Integer_List_Type)
> return Abstract_Integer_Collections.Iterator_Type'Class is
> begin
> return Integer_List_Iterator_Type'
> (Abstract_Integer_Collections.Iterator_Type with
> Next_Cell => Collection.First_Cell);
> end New_Iterator_For;
>
In general one might like to have more than one
iterator for the same collection type, each
iterator implementing a different traversal
policy but all having the same protocol.
So for example, in the package Integer_Lists
one might want to derive a second concrete
type from Abstract_Integer_Collections.Iterator_Type .
However, the problem arises that the function
New_Iterator_For is a classwide function rooted
at Abstract_Integer_Collections.Iterator_Type
and as it stands will always return the first
type of iterator, namely Integer_List_Iterator_Type.
A possible solution is the following.
Define a (generic) abstract collection which
has those operations which do not mention
iterators.
Define a (generic) abstract iterator.
Define a (generic) concrete collection which
conforms to the abstract collection.
Then, for each iterator type, define a
(generic) package which is a child of
the (generic) concrete collection.
Each child package can instantiate its
own abstract iterator and provide its
own implementation of New_Iterator_For,
which in fact returns the appropriate
concrete iterator. Within each child
package the implementation of the concrete
collection is visible.
For example, (with some naming and
naming convention differences)
generic
type ItemType (<>) is private;
package AbstractAppendableCollection_P is
type AbstractAppendableCollection is abstract tagged null record;
function isNotEmpty
( theCollection : AbstractAppendableCollection )
return Boolean
is abstract;
procedure append
( theItem : in ItemType;
toTheCollection : in out AbstractAppendableCollection)
is abstract;
procedure removeTheLastItemFrom
( theCollection : in out AbstractAppendableCollection)
is abstract;
-- precondition: isNotEmpty( theCollection );
end;
generic
type CollectionType (<>) is private;
type ItemType (<>) is private;
package AbstractIterator_P is
type AbstractIterator is abstract tagged null record;
function aNewIteratorFor
( theCollection : CollectionType )
return AbstractIterator'Class
is abstract;
-- precondition: isNotEmpty( theCollection )
-- after creation the iterator points to the first item in the
collection
function theCurrentItem
( theIterator : AbstractIterator )
return ItemType
is abstract;
function atTheEnd
( theIterator : AbstractIterator )
return Boolean
is abstract;
procedure advance
( theIterator : in out AbstractIterator )
is abstract;
-- precondition : not(atTheEnd())
procedure reset
( theIterator : in out AbstractIterator )
is abstract;
-- reset the state of the iterator to be that after creation
end;
with AbstractAppendableCollection_P;
generic
type ItemType (<>) is private;
package AppendableCollection_P is
package ItemTypeAbstractAppendableCollection_P
is new AbstractAppendableCollection_P(ItemType => ItemType);
use ItemTypeAbstractAppendableCollection_P;
type AppendableCollection
is new AbstractAppendableCollection with private;
function isNotEmpty
( theCollection : AppendableCollection )
return Boolean;
procedure append
( theItem : in ItemType;
toTheCollection : in out AppendableCollection);
procedure removeTheLastItemFrom
( theCollection : in out AppendableCollection);
-- precondition: isNotEmpty( theCollection );
private
type AppendableCollection
is new AbstractAppendableCollection with null record;
-- (with null record until I get round to implementing it!)
end;
with AbstractIterator_P;
generic
package AppendableCollection_P.ForwardsIterator_P is
package ItemTypeAbstractIterator_P
is new AbstractIterator_P
(CollectionType => AppendableCollection,
ItemType => ItemType );
use ItemTypeAbstractIterator_P;
type ForwardsIterator is new AbstractIterator with private;
function aNewIteratorFor
( theCollection : AppendableCollection )
return AbstractIterator'Class;
function theCurrentItem
( theIterator : ForwardsIterator )
return ItemType;
function atTheEnd
( theIterator : ForwardsIterator )
return Boolean;
procedure advance
( theIterator : in out ForwardsIterator );
-- precondition : not(atTheEnd())
procedure reset
( theIterator : in out ForwardsIterator );
-- reset the state of the iterator to be that after creation
private
type ForwardsIterator is new AbstractIterator with null record;
-- (with null record until I get round to implementing it!)
end;
-- similar child packages for BackwardsIterator etc.
The above specifications compile but I have yet to write
some bodies and check that this is really a workable scheme.
next prev parent reply other threads:[~1996-08-22 0:00 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
1996-08-20 0:00 Translate this into Ada Richard Irvine
1996-08-21 0:00 ` David Weller
1996-08-21 0:00 ` Norman H. Cohen
1996-08-22 0:00 ` Richard Irvine [this message]
1996-08-22 0:00 ` Norman H. Cohen
1996-08-22 0:00 ` Richard Irvine
1996-08-29 0:00 ` Robert A Duff
-- strict thread matches above, loose matches on Subject: below --
1996-08-21 0:00 Spasmo
1996-08-21 0:00 ` Richard Irvine
1996-08-28 0:00 ` Robert A Duff
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox