comp.lang.ada
 help / color / mirror / Atom feed
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.




  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