comp.lang.ada
 help / color / mirror / Atom feed
From: Nick Roberts <nick.roberts@acm.org>
Subject: Re: Help with a Remote Type / Iterator
Date: Mon, 01 Dec 2003 23:00:04 +0000
Date: 2003-12-01T23:00:04+00:00	[thread overview]
Message-ID: <bqgh5i$22js2q$1@ID-25716.news.uni-berlin.de> (raw)
In-Reply-To: <BSyyb.60537$t01.50475@twister.socal.rr.com>

Michael Lamarre wrote:

> package A is
> 
>    pragma REMOTE_TYPES(A);
> 
>    type RECORD_TYPE is tagged limited private;
> 
>    type RECORD_PTR_TYPE is access all RECORD_TYPE'CLASS;
> 
>    -- various operations on RECORD_TYPEs.
> 
> private
> 
>    type RECORD_TYPE is tagged limited record
>       -- Various record fields.
>    end record;
> 
> end A;
> 
> package A.CHILD
> 
>    pragma REMOTE_TYPES(CHILD);
> 
>    type COLLECTION_TYPE(CAPACITY : NATURAL) is tagged limited private;
> 
>    type COLLECTION_PTR_TYPE is access all COLLECTION_TYPE'CLASS;
> 
>    -- Various operations on COLLECTION_TYPEs.
> 
> private
> 
>    type REC_ARRAY_TYPE is array (NATURAL range <>) of RECORD_PTR_TYPE;
> 
>    type COLLECTION_TYPE(CAPACITY : NATURAL) is tagged limited record
>       RECORD_ARRAY : REC_ARRAY_TYPE(1..CAPACITY);
>       -- Various other fields.
>    end record;
> 
> end A.CHILD;

I don't think it is necessary for your COLLECTION_TYPE to be tagged, and I 
don't think it is necessary to export an access type designating it (or 
it's class). I think you only need to export a COLLECTION_TYPE, with a few 
appropriate operations. As a file is essentially a glorified iterator, I 
suggest it is appropriate to look at the Ada.*_IO packages as a starting 
point (these are the nearest thing I can think of as being a standard way 
to iterate over a remote type).

I would also suggest a rule of thumb that might help you. It is generally 
not a useful idea to declare a 'general purpose' access type of a remote 
type in the same specification. For one thing, it is a remote access type; 
this is really rather a special kind of access type, to be used (only) in 
those circumstances when it is especially called for.

Let me now suggest an amended skeleton:

package A is

    pragma REMOTE_TYPES(A);

    type RECORD_TYPE is tagged limited private;

    -- various operations on RECORD_TYPEs.

private

    type RECORD_TYPE is tagged limited record
       -- Various record fields.
    end record;

end A;

package A.CHILD

    pragma REMOTE_TYPES(CHILD);

    type COLLECTION_TYPE is limited private;

    -- Management operations for COLLECTION_TYPE:

    procedure Create (Collection: in out Collection_Type;
                      CAPACITY:   in     NATURAL);

    procedure Copy (Original:  in     Collection_Type;
                    Duplicate: in out Collection_Type);

    procedure Delete (Collection: in out Collection_Type);

    procedure Reset (Collection: in Collection_Type);

    -- Read and Write for COLLECTION_TYPE:

    type RECORD_PTR_TYPE is access [all] RECORD_TYPE'CLASS;

    procedure Write (Collection: in Collection_Type;
                     Item:       in RECORD_PTR_TYPE);

    procedure Read (Collection: in  Collection_Type;
                    Item:       out RECORD_PTR_TYPE);

    function End_of_File (Collection: in Collection_Type) return Boolean;

    -- Other operations on COLLECTION_TYPEs?

    Capacity_Error: exception;

private;

    protected type COLLECTION_HOLDER (CAPACITY : NATURAL) is

       procedure Reset;
       procedure Write (Item: in  RECORD_PTR_TYPE);
       procedure Read  (Item: out RECORD_PTR_TYPE);
       function End_of_File return Boolean;

    private

       Data:    array (1..Capacity) of RECORD_PTR_TYPE;
       Count:   Natural := 0;
       Pointer: Natural := 0; -- 0 for 'end of file'

    end;

    type COLLECTION_TYPE is access COLLECTION_HOLDER;

end A.CHILD;

I hope it's fairly clear how this is intended to work. The most important 
feature is that, instead of having a separate iterator type, I've opted for 
the conceit of allowing one client to iterate over a collection, and if 
another client wishes to do the same (in parallel), it simply makes a copy 
collection of its own (using the Copy procedure). There must be lots of 
alternate designs on this general theme. You may need to introduce 
read/write modes and a more sophisticated Reset procedure.

Since COLLECTION_TYPE is implemented as a remote access type, it hides the 
indirection away from the client. It provides the exported type upon which 
the operations needed by the client can be hung, yet it invisibly allows 
the actual collections -- in objects of the protected type 
COLLECTION_HOLDER -- to be allocated inside the server. You can be sure 
that most implementations of the File_Type in the Ada.*_IO packages are 
(roughly) the same.

Note how I declare RECORD_PTR_TYPE in the CHILD package. It will be a 
remote access type (as it needs to be in this case), but it still makes 
more sense to declare it here, since it is in this package that all the 
operations upon it are also declared. It may, for example, make more sense 
to declare it as a pool-specific type, for this particular use.

-- 
HTH
Nick Roberts




      parent reply	other threads:[~2003-12-01 23:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-12-01  3:48 Help with a Remote Type / Iterator Michael Lamarre
2003-12-01  5:31 ` Robert I. Eachus
2003-12-01 13:37   ` Michael Lamarre
2003-12-02 23:17     ` Robert I. Eachus
2003-12-03  4:46       ` Michael Lamarre
2003-12-01 23:00 ` Nick Roberts [this message]
replies disabled

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